我正在使用事件ItemSelectionChanged
和SelectedIndexChanged
ListView 类来回答这个问题。
代码如下,唯一似乎仍然存在的错误是,当用户使用橡皮筋选择时,我也使用 250ms 计时器,而不仅仅是单击或双击选择。
internal Form1()
{
InitializeComponent();
t.Tick += T_Tick;
}
internal bool santinela = false;
internal void T_Tick(object sender, EventArgs e)
{
t.Stop();
if (!santinela)
{
bool newVal = selectionChangedItem.Selected;
selectionChangedItem.Checked =
selectionChangedItem.Selected = newVal;
santinela = true;
}
}
internal Timer t = new Timer()
{
Interval = 250
};
internal bool santinela3 = true;
internal void listView1_ItemCheck(object sender, ItemCheckEventArgs e)
{
if (santinela3)
{
if (e.CurrentValue == CheckState.Checked)
{
listView1.SelectedIndices.Remove(e.Index);
}
else if (e.CurrentValue == CheckState.Unchecked)
{
listView1.SelectedIndices.Add(e.Index);
}
}
}
internal void listView1_ItemActivate(object sender, EventArgs e)
{
if (listView1.SelectedItems.Count > 0)
{
MessageBox.Show(listView1.SelectedItems[0].Text);
}
}
internal ListViewItem selectionChangedItem = null;
internal bool santinela2 = true;
internal void listView1_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
{
if (!santinela2)
{
return;
}
if (t.Enabled)
{
santinela = true;
t.Stop();
// double click: both clicks must be done in the same place
if (e.Item == selectionChangedItem)
{
if (!e.IsSelected)
{
santinela2 = true;
e.Item.Selected = true;
santinela2 = false;
}
listView1_ItemActivate(sender, EventArgs.Empty);
}
selectionChangedItem = null;
}
else
{
santinela = false;
t.Stop();
selectionChangedItem = e.Item;
t.Start();
}
}
internal void listView1_SelectedIndexChanged(object sender, EventArgs e)
{
if (listView1.SelectedIndices.Count == 0)
{
santinela = true;
t.Stop();
selectionChangedItem = null;
santinela3 = false;
for (int i = 0; i < listView1.CheckedItems.Count; ++i)
{
listView1.CheckedItems[i].Checked = false;
}
santinela3 = true;
}
}
相关设计器代码如下:
System.Windows.Forms.ListViewItem listViewItem1 = new System.Windows.Forms.ListViewItem("item1");
System.Windows.Forms.ListViewItem listViewItem2 = new System.Windows.Forms.ListViewItem("item2");
this.listView1 = new System.Windows.Forms.ListView();
this.SuspendLayout();
//
// listView1
//
this.listView1.CheckBoxes = true;
listViewItem1.StateImageIndex = 0;
listViewItem2.StateImageIndex = 0;
this.listView1.Items.AddRange(new System.Windows.Forms.ListViewItem[] {
listViewItem1,
listViewItem2});
this.listView1.Location = new System.Drawing.Point(12, 12);
this.listView1.Name = "listView1";
this.listView1.Size = new System.Drawing.Size(401, 327);
this.listView1.TabIndex = 0;
this.listView1.UseCompatibleStateImageBehavior = false;
this.listView1.ItemActivate += new System.EventHandler(this.listView1_ItemActivate);
this.listView1.ItemCheck += new System.Windows.Forms.ItemCheckEventHandler(this.listView1_ItemCheck);
this.listView1.ItemSelectionChanged += new System.Windows.Forms.ListViewItemSelectionChangedEventHandler(this.listView1_ItemSelectionChanged);
this.listView1.SelectedIndexChanged += new System.EventHandler(this.listView1_SelectedIndexChanged);
更新:由于计时器,我面临的问题是,在用橡皮筋悬停 ListViewItem 后,在检查项目之前,计时器会出现无用的延迟。当用户调整大小/移动橡皮筋以便不再检查 ListViewItem 时,存在相同的延迟。如果用户不知道该非标准延迟,则选择可能是错误的。