我需要为winform listview添加鼠标多选支持。 (用户将点击一个项目并将其拖动到第五个并且她将能够选择项目1到5)我认为我应该继承listview以向其添加新功能但我不知道哪些事件或我应该添加方法。我该怎么做?提前谢谢。
答案 0 :(得分:1)
自定义ListView
并覆盖MouseMove
(红利 - Ctr + A 支持):
[System.ComponentModel.DesignerCategory("Code")]
public class MyListView : ListView
{
protected override void OnMouseMove(MouseEventArgs e)
{
// easy mouse selection
if (MouseButtons == MouseButtons.Left)
{
var item = this.HitTest(e.Location).Item;
if (item != null)
item.Selected = true;
}
base.OnMouseMove(e);
}
protected override void OnKeyDown(KeyEventArgs e)
{
// ctrl-a - select all
if (e.KeyCode == Keys.A && e.Control)
SelectAll();
base.OnKeyDown(e);
}
}
这不是最好的实现,如果你移动得太快,那么有些项目将被跳过。
ListView
是一个特殊的控件,因为它有不同的视图来呈现数据。在图标视图中,您可以通过使用鼠标绘制矩形来选择多个项目(按下按钮,绘制矩形,释放)。同样适用于详细信息视图。所有与矩形项相交的将被选中。重要提示:这种选择方式需要从未被项目区域开始绘制矩形。
问题:在详细信息中查看位于最后一列右侧和最后一项底部的未占用区域。通常列占据所有水平空间,项目全部垂直,因此不存在这样的区域。所以这种选择方式不起作用!
在ListView
中选择多个项目的其他众所周知的可能性是选择第一个项目,按 Shift 然后单击最后一个项目。将选择范围中的所有项目(或图标视图中的矩形)。或者按 Ctr 并单击项目逐个切换选择。
答案 1 :(得分:1)
Sinatrs方法是一个好主意。
使用“详细信息”视图,您可以尝试这样的操作,以获得类似行为的Windows资源管理器:
Int32 firstClickItemIndex = 0;
public Boolean numInRange(Int32 num, Int32 first, Int32 last)
{
return first <= num && num <= last;
}
private void listView1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.A && e.Control)
{
foreach (ListViewItem lvItem in listView1.Items)
lvItem.Selected = true;
}
}
private void listView1_MouseDown(object sender, MouseEventArgs e)
{
if (MouseButtons == MouseButtons.Left && listView1.HitTest(e.Location).Item != null)
firstClickItemIndex = listView1.HitTest(e.Location).Item.Index;
}
private void listView1_MouseMove(object sender, MouseEventArgs e)
{
if (MouseButtons == MouseButtons.Left)
{
ListViewItem lvItem = listView1.HitTest(e.Location).Item;
if (lvItem != null)
{
lvItem.Selected = true;
if (listView1.SelectedItems.Count > 1)
{
Int32 firstSelected = listView1.SelectedItems[0].Index;
Int32 lastSelected = listView1.SelectedItems[listView1.SelectedItems.Count - 1].Index;
foreach (ListViewItem tempLvItem in listView1.Items)
{
if (numInRange(tempLvItem.Index, firstSelected, lastSelected) && (numInRange(tempLvItem.Index, lvItem.Index, firstClickItemIndex) || numInRange(tempLvItem.Index, firstClickItemIndex, lvItem.Index)))
{
tempLvItem.Selected = true;
}
else
{
tempLvItem.Selected = false;
}
}
}
}
}
}