如何防止ListBox.SelectedIndexChanged事件?

问题描述:

我在C#2.0窗体表单应用程序中使用了一个列表框。填充列表框的方法是如何防止ListBox.SelectedIndexChanged事件?

private void PopulateListBox(ListBox lb, ReportColumnList reportColumnList) 
    { 
     lb.DataSource = reportColumnList.ReportColumns; 
     lb.DisplayMember = "ColumnName"; 
     lb.ValueMember = "ColumnName"; 
    } 

然而,当它执行它还会调用列表框的SelectedIndexChanged事件处理程序,即使我没有在设定上述方法选择的指数的方法。如何防止为上述代码调用SelectedIndexChanged事件处理程序?

我希望仅当用户在ListBox中进行选择时才会调用该事件。或者是否有任何其他事件仅用于用户使用鼠标单击选择列表框项目?

另一方面,即使用户单击列表框中的空白区域,SelectedIndexChanged事件也会被触发。所以我想知道它与MouseClick事件有什么不同?

+1

在大多数情况下,你不能防止对象引发事件。您只能选择停止收听事件通知。 – Gishu 2009-05-25 05:59:25

+0

我的意思是,如果我能以某种方式防止我的代码的一部分,火灾的事件。但是正如我们所看到的,我没有什么可以做的,因为PopulateListBox()中的所有三行都需要:) – 2009-05-25 06:24:46

可以填充使用lb.Items.AddRange()的列表框,而不是设置数据源。除了不触发SelectedIndexChanged之外,这也不会预先选择第一个项目。

lb.Items.Clear(); 
lb.Items.AddRange(reportColumnList.ReportColumns.ToArray()); 

有三种方法可以解决这个问题。

答)不要挂钩到SelectedIndexChanged事件,直到您调用此方法后。 B)在你的班级中有一个初始设置为true的私有布尔值。在您的PopulateListBox方法开始时,将其设置为false,并在最后将其设置为true。在您的SelectedIndexChanged的事件处理程序中,如果标志为false,则返回并不执行任何操作。

C)在你的PopulateListBox方法的开始,从事件解除(this.listbox1.SelectedIndexChanged - = myMethod;),然后在方法完成之前,重新挂钩该事件。

+0

感谢您的回答。但是,而不是上述步骤,如果我使用MouseClick事件来处理用户选择更改会怎么样?这样,只有在用户选择发生变化时才会触发MouseClick事件,并且在调用PopulateListBox()时不会调用MouseClick事件。在这种情况下使用MouseClick事件有什么缺点吗?我测试了它,它工作正常,但我想知道一些我将来可能面临的隐患,因此。 – 2009-05-25 06:23:24

+0

无法使用MouseClick方法。原因:对于MultiExtended列表框,当点击鼠标时,即使我选择了多个项目,选定的索引计数也不会反映该项目。只有在调用SelectedIndexChanged时,我才能得到正确的计数。 – 2009-05-25 06:36:55

您应该知道,即使您未处理该事件,列表中的第一项仍然会在分配数据源属性时自动选中。为了强制用户进行选择,您需要取消选择自动选择的项目。

如果您的SelectedIndexChanged事件处理程序在选择某个项目时触发了某些功能,您可能仍然希望阻止其执行。一种方法是跟踪代码是否正在填充列表框。如果正在填充列表框而触发SelectedIndexChanged事件,你能避免执行这些操作:

private bool _populating = false; 
private void PopulateListBox(ListBox lb, ReportColumnList reportColumnList) 
{ 
    _populating = true; 
    lb.DataSource = reportColumnList.ReportColumns; 
    lb.DisplayMember = "ColumnName"; 
    lb.ValueMember = "ColumnName"; 

    // clear the automatically made selection 
    lb.SelectedIndex = -1; 
    _populating = false; 
} 

private void ListBox_SelectedIndexChanged(object sender, EventArgs e) 
{ 
    if (!_populating) 
    { 
     // perform the action associated with selecting an item 
    } 

} 

有一个最简单的回答了这个问题: 的代码片段下面可以围绕建议的工作。

lstBxState.SelectionMode = SelectionMode.None; 
lstBxState.DataSource = lstStates; 
lstBxState.ValueMember = "StateId"; 
lstBxState.DisplayMember = "StateName"; 
lstBxState.ClearSelected(); 
lstBxState.SelectionMode = SelectionMode.One; 

这意味着,只需将选择模式设置为“无”,并愉快地将数据绑定到控件。然后继续并将模式更改为所需模式(这里我已将其更改为“一个”,您也可以选择“多个”)。

里面的SelectedIndexChanged方法,只是在if语句,说坑,如果SelectedIndex == -1别的什么也不做,做任何你想要在这个方法来做,可能不是最有效的代码,但对我来说:)

private void PopulateListBox(ListBox lb, ReportColumnList reportColumnList) 
{ 

    lb.SelectedIndexChanged -= this.*MethodnamewhichhandlesthisEvent*; //unset eventhandler 

    lb.DataSource = reportColumnList.ReportColumns; 
    lb.DisplayMember = "ColumnName"; 
    lb.ValueMember = "ColumnName"; 

    lb.SelectedIndexChanged += this.*MethodnamewhichhandlesthisEvent*; //set the eventhandler 
} 
工作

基本上从事件中删除委托,然后在完成后添加。

我的情况可能是独一无二的,但我会在这里发布以防万一它有助于某人。

我在做Items.AddRange来填充我的ListBox而不是绑定。我不知道为什么,但在PostBack上,SelectedIndex从-1变为0.这可能是因为我的ListBox是SelectionMode="Single"

我的修复是对的SelectedIndex手动设置为0,而不是-1人口后:

listBox.Items.AddRange(items); 
listBox.SelectedIndex = 0;