我想实现一个 ListView ,它将具有现在的 SelectedItems 列表, 但它也有一个单独的项目在光标下(可以用鼠标/键盘移动)。 项目选择将通过特殊操作完成(例如空格键)。
换句话说,我想抑制 ListView 上的选择,并且只在正常选择时更改 FocusedItem 。
我认为我应该对 ListView 的 FocusedItem 和 SelectedItems 属性做些什么, 但问题是点击一个项目会选择它(也会改变焦点)。
解决方案是捕获可以更改选择的 keydown 和 mouseclick 事件,并根据事件仅将 FocusedItem 更改为项目(鼠标点击鼠标指针下的项目和 keydown 上/下箭头中当前项目上方/下方的项目。然后我只会在我的特殊事件(空格键按下)上向 SelectedItems 集合中添加项目。
我要问的是,是否有更优雅的方法解决这个问题或上述解决方案尽可能简单。感谢
答案 0 :(得分:0)
好的,抓住这个。
我需要继承ListView(ListViewEx);
处理键盘选择事件:
private void ListViewEx_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyData == Keys.Down)
{
//move focus down
if (this.FocusedItem.Index + 1 < this.Items.Count)
{
this.FocusedItem = this.Items[this.FocusedItem.Index + 1];
this.FocusedItem.EnsureVisible();
e.Handled = true;
}
}
else if (e.KeyData == Keys.Up)
{
if (this.FocusedItem.Index - 1 < this.Items.Count)
{
this.FocusedItem = this.Items[this.FocusedItem.Index - 1];
this.FocusedItem.EnsureVisible();
e.Handled = true;
}
}
}
和WndProc中的鼠标事件
这样左键单击/键盘向上/向下移动焦点,键盘右键单击进行选择
protected override void WndProc(ref Message m)
{
const int WM_LBUTTONDOWN = 0x0201;
const int WM_RBUTTONDOWN = 0x204;
switch (m.Msg)
{
case WM_LBUTTONDOWN:
Point pos = this.PointToClient(Cursor.Position);
var item = GetItemAt(pos.X, pos.Y);
this.FocusedItem = item;
break;
case WM_RBUTTONDOWN:
pos = this.PointToClient(Cursor.Position);
item = GetItemAt(pos.X, pos.Y);
item.Selected = !item.Selected;
break;
default:
base.WndProc(ref m);
break;
}
}