【问题标题】:How to prevent ListBox.SelectedIndexChanged event?如何防止 ListBox.SelectedIndexChanged 事件?
【发布时间】:2009-05-25 05:33:01
【问题描述】:

我在我的 C#2.0 Windows 窗体应用程序中使用了一个列表框。填充列表框的方法是

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

但是,当它执行该方法时,它也会调用列表框的 SelectedIndexChanged 事件处理程序,即使我没有在上面的方法中设置选定的索引。如何防止上述代码调用 SelectedIndexChanged 事件处理程序?

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

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

【问题讨论】:

  • 在大多数情况下,您无法阻止对象引发事件。您只能选择停止侦听事件通知。
  • 我的意思是如果我能以某种方式阻止我的代码中触发事件的那部分。但正如我们所见,我无能为力,因为 PopulateListBox() 中的所有三行都是 reqd :)

标签: c# .net winforms


【解决方案1】:

您可以通过三种方式解决此问题。

A) 在调用此方法之前,不要挂钩 SelectedIndexChanged 事件。

B) 在您的类中有一个私有布尔值,该值最初设置为 true。在 PopulateListBox 方法开始时,将其设置为 false,最后将其设置回 true。在 SelectedIndexChanged 的​​事件处理程序中,如果标志为 false,则返回并且什么也不做。

C) 在您的 PopulateListBox 方法开始时,从事件中取消挂钩 (this.listbox1.SelectedIndexChanged -= myMethod;),然后在方法完成之前,重新挂钩到该事件。

【讨论】:

  • 感谢您的回答。但是,如果我使用 MouseClick 事件来处理用户选择更改,而不是上述步骤,该怎么办?这样,只有在用户选择发生变化时才会触发 MouseClick 事件,并且不会在调用 PopulateListBox() 时被调用。在这种情况下使用 MouseClick 事件有什么缺点吗?我对其进行了测试,它运行良好,但我想知道我将来可能会因此遇到一些隐藏的错误。
  • 不能使用鼠标点击方法。原因:对于 MultiExtended 列表框,当触发鼠标单击时,即使我选择了多个项目,所选索引计数也不会反映这一点。只有当 SelectedIndexChanged 被调用时,我才能得到正确的计数。
  • 我通常选择选项 A。+1
  • 我不能使用 A,因为我页面上的所有列表框都在使用 PopulateListBox()。相反,出于某些其他原因,我使用了 Kim 的填充方法和 bool 方法。
  • @Rashmi:更不用说鼠标不是计算机上唯一的输入设备。
【解决方案2】:

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

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

【讨论】:

  • 是的……这正是我想要的。我根据您的回答更改了我的代码,它就像一个魅力:) 谢谢一百万,Kim!!!
【解决方案3】:

这个问题有一个最简单的答案: 下面的代码 sn-p 可以建议解决方法。

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

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

【讨论】:

  • “System.Web.UI.WebControls.ListSelectionMode”不包含“无”的定义
  • 这个问题是关于 Windows 窗体的,该命名空间用于 ASP.NET 控件。
【解决方案4】:

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

如果您的 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
    }

}

【讨论】:

    【解决方案5】:

    SelectedIndexChanged 方法中,只需插入一个if 语句,如果SelectedIndex == -1 什么都不做,在这个方法中做任何你想做的事情,可能不是最有效的代码,但对我有用:)

    【讨论】:

      【解决方案6】:

      我的情况可能很独特,但我会在这里发布以防万一它对某人有所帮助。

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

      我的解决方法是在填充后手动将 SelectedIndex 设置为 0 而不是 -1:

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

      【讨论】:

        【解决方案7】:
        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
        }
        

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

        【讨论】:

          猜你喜欢
          • 2015-11-21
          • 2019-10-31
          • 2013-02-18
          • 2010-09-16
          • 1970-01-01
          • 1970-01-01
          • 2020-09-09
          • 2018-07-11
          • 2014-11-08
          相关资源
          最近更新 更多