我如何模仿Windows资源管理器在DataGridView中的多选/拖放行为?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了我如何模仿Windows资源管理器在DataGridView中的多选/拖放行为?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3561字,纯文字阅读大概需要6分钟。
内容图文
![我如何模仿Windows资源管理器在DataGridView中的多选/拖放行为?](/upload/InfoBanner/zyjiaocheng/947/e7689f5bc8104b8cae5e6216dd579eb5.jpg)
我试图模仿Windows资源管理器处理多项选择的方式.在默认的DataGridView中,可以使用Ctrl单击来选择多个项目.但是,如果释放Ctrl键,然后尝试拖放所选项目,则它将清除所选项目,而仅选择“命中”行.我在网上某处找到了以下解决方案.
protected override onm ouseDown(MouseEventArgs e)
{
int hitRowIndex = HitTest(e.X, e.Y).RowIndex;
if(!SelectedRows.Contains(Rows[hitRowIndex]))
{
base.OnMouseDown();
}
}
但是,这会引起其他副作用.按下CTRL键并在选定项目上向下拖动时,该项目保持选中状态.这是有道理的,因为如果选择了单击的行,则会绕过mousedown事件.从Windows资源管理器的行为来看,看起来直到按住Mouse键才可以取消对按住CTRL键的项目的取消选择.有没有人尝试这样做?
解决方法:
我创建了一个自定义组件来解决此问题,以及在datagridview中进行多重选择时遇到的其他一些烦人的问题.这是代码,希望对任何人有帮助:
public partial class CustomDataGridView : DataGridView
{
public CustomDataGridView()
{
InitializeComponent();
}
public CustomDataGridView(IContainer container)
{
container.Add(this);
InitializeComponent();
}
private bool _delayedMouseDown = false;
private Rectangle _dragBoxFromMouseDown = Rectangle.Empty;
private Func<object> _getDragData = null;
public void EnableDragDrop(Func<object> getDragData)
{
_getDragData = getDragData;
}
protected override void OnCellMouseDown(DataGridViewCellMouseEventArgs e)
{
base.OnCellMouseDown(e);
if (e.RowIndex >= 0 && e.Button == MouseButtons.Right)
{
var currentRow = this.CurrentRow.Index;
var selectedRows = this.SelectedRows.OfType<DataGridViewRow>().ToList();
var clickedRowSelected = this.Rows[e.RowIndex].Selected;
this.CurrentCell = this.Rows[e.RowIndex].Cells[e.ColumnIndex];
// Select previously selected rows, if control is down or the clicked row was already selected
if ((Control.ModifierKeys & Keys.Control) != 0 || clickedRowSelected)
selectedRows.ForEach(row => row.Selected = true);
// Select a range of new rows, if shift key is down
if ((Control.ModifierKeys & Keys.Shift) != 0)
for (int i = currentRow; i != e.RowIndex; i += Math.Sign(e.RowIndex - currentRow))
this.Rows[i].Selected = true;
}
}
protected override void onm ouseDown(MouseEventArgs e)
{
var rowIndex = base.HitTest(e.X, e.Y).RowIndex;
_delayedMouseDown = (rowIndex >= 0 &&
(SelectedRows.Contains(Rows[rowIndex]) || (ModifierKeys & Keys.Control) > 0));
if (!_delayedMouseDown)
{
base.OnMouseDown(e);
if (rowIndex >= 0)
{
// Remember the point where the mouse down occurred.
// The DragSize indicates the size that the mouse can move
// before a drag event should be started.
Size dragSize = SystemInformation.DragSize;
// Create a rectangle using the DragSize, with the mouse position being
// at the center of the rectangle.
_dragBoxFromMouseDown = new Rectangle(
new Point(e.X - (dragSize.Width / 2), e.Y - (dragSize.Height / 2)), dragSize);
}
else
// Reset the rectangle if the mouse is not over an item in the datagridview.
_dragBoxFromMouseDown = Rectangle.Empty;
}
}
protected override void onm ouseUp(MouseEventArgs e)
{
// Perform the delayed mouse down before the mouse up
if (_delayedMouseDown)
{
_delayedMouseDown = false;
base.OnMouseDown(e);
}
base.OnMouseUp(e);
}
protected override void onm ouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
// If the mouse moves outside the rectangle, start the drag.
if (_getDragData != null && (e.Button & MouseButtons.Left) > 0 &&
_dragBoxFromMouseDown != Rectangle.Empty && !_dragBoxFromMouseDown.Contains(e.X, e.Y))
{
if (_delayedMouseDown)
{
_delayedMouseDown = false;
if ((ModifierKeys & Keys.Control) > 0)
base.OnMouseDown(e);
}
// Proceed with the drag and drop, passing in the drag data
var dragData = _getDragData();
if (dragData != null)
this.DoDragDrop(dragData, DragDropEffects.Move);
}
}
}
内容总结
以上是互联网集市为您收集整理的我如何模仿Windows资源管理器在DataGridView中的多选/拖放行为?全部内容,希望文章能够帮你解决我如何模仿Windows资源管理器在DataGridView中的多选/拖放行为?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。