如何防止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事件有什么不同?
可以填充使用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;),然后在方法完成之前,重新挂钩该事件。
感谢您的回答。但是,而不是上述步骤,如果我使用MouseClick事件来处理用户选择更改会怎么样?这样,只有在用户选择发生变化时才会触发MouseClick事件,并且在调用PopulateListBox()时不会调用MouseClick事件。在这种情况下使用MouseClick事件有什么缺点吗?我测试了它,它工作正常,但我想知道一些我将来可能面临的隐患,因此。 – 2009-05-25 06:23:24
无法使用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;
在大多数情况下,你不能防止对象引发事件。您只能选择停止收听事件通知。 – Gishu 2009-05-25 05:59:25
我的意思是,如果我能以某种方式防止我的代码的一部分,火灾的事件。但是正如我们所看到的,我没有什么可以做的,因为PopulateListBox()中的所有三行都需要:) – 2009-05-25 06:24:46