在ListView中捕获未选择的全部——SelectedIndexChanged触发两次

本文关键字:SelectedIndexChanged 两次 全部 ListView 选择 | 更新日期: 2023-09-27 17:50:39

基本上,我有一个项目的ListView。当选中一个时,右侧会出现一个文本框,显示该项的更多详细信息(抓取该项数据需要一些时间)。我想要的行为是隐藏这个文本框的右侧,当所有的项目被取消选中。

        private void listView1_SelectedIndexChanged(object sender, EventArgs e) {
            // should only be 1 item selected, it's not a multi-select listview
            ListView.SelectedListViewItemCollection collection = this.listView1.SelectedItems;
            if (collection.Count == 0) {
                this.label2.Visible = false;
            }    
            foreach (ListViewItem item in collection) {
                this.label2.Visible = true;
                getSideInformation(item.Text);
            }
        }

我注意到一个闪烁的框,当我简单地选择另一个项目。我做了一些研究,将我的代码更改为:

        private void listView1_SelectedIndexChanged(object sender, EventArgs e) {
            // should only be 1 item selected, it's not a multi-select listview
            ListView.SelectedListViewItemCollection collection = this.listView1.SelectedItems;
            if (collection.Count == 0) {
                this.label2.Text = "Unselected all!"    
            }
            foreach (ListViewItem item in collection) {
                getSideInformation(item.Text);
            }
        }

基本上,我不再隐藏框,但只是改变文本,如果它是一个选择改变事件,0项被选中。我发现,对于一个简单的选择另一个项目,这个事件实际上会触发两次(一次是0项,第二次是选择新项目)。因此,如果我之前选择了一个项目并更改为另一个项目,那么在加载任何侧信息时,我的框将始终显示"未选中全部!"。

是否有办法区分所有未选择项目的实际事件触发与选择另一个项目的0个项目的初始事件触发?

在ListView中捕获未选择的全部——SelectedIndexChanged触发两次

你可以注册到ListView的ItemSelectionChangedEvent。

        this.listView1.ItemSelectionChanged += this.HandleOnListViewItemSelectionChanged;
        private void HandleOnListViewItemSelectionChanged(Object sender, ListViewItemSelectionChangedEventArgs e)
        {
            if (e.IsSelected)
            {
                this.detailsLabel.Text = this.GetDetails(e.Item);
            }
            else
            {
                this.detailsLabel.Text = String.Empty;
            }
        }

我发现最好的解决方案是暂时设置事件处理程序为Application.Idle,并从那里进行检查,如下所示:

bool handled;
private void listView1_SelectedIndexChanged(object sender, EventArgs e) {
    if (!handled)
    {   handled = true;
        Application.Idle += SelectionChangeDone;   }
}
private void SelectionChangeDone(object sender, EventArgs e) {
    Application.Idle -= SelectionChangeDone;
    handled = false;
    ListView.SelectedListViewItemCollection collection = this.listView1.SelectedItems;
    if (collection.Count == 0)
        this.label2.Text = "Unselected all!"
    foreach (ListViewItem item in collection)
        getSideInformation(item.Text);
}

ItemSelectionChanged还是SelectedIndexChanged都不重要。在这种情况下两者都可以正常工作。

非常感谢Grammarian在这里回答了本质上相同的问题:https://stackoverflow.com/a/26393234/2532220

在任何可以选择多个项目的控件中,SelectedIndexChanged事件都会触发两次。一,删除未选中的项目,然后添加选中的项目。当您第一次单击时,所选项集合为空,因此只触发一次。下次会发射两次。

您可以在事件块中使用下面的代码来检查是否SelectedIndexChange事件直接触发,因为控件或由于来自其他用户控件/页面的回发事件

string id= Request.Form["__EVENTTARGET"];
if(!string.IsNullorEmpty(id))
{
//your code here
}

你可以这样做:

         private bool isInitialized = false;
         private void listView1_SelectedIndexChanged(object sender, EventArgs e) {
             if (isInitialized) {
                 ListView.SelectedListViewItemCollection collection = this.listView1.SelectedItems;
                 if (collection.Count == 0) {
                     this.label2.Text = "Unselected all!";
                 }
                 foreach (ListViewItem item in collection) {
                     getSideInformation(item.Text);
                 }
             }
             isInitialized = true;
        }

这将确保第一次触发被忽略

相关文章:
  • 没有找到相关文章