【问题标题】:In C# WPF, why is my TabControl's SelectionChanged event firing too often?在 C# WPF 中,为什么我的 TabControl 的 SelectionChanged 事件触发太频繁?
【发布时间】:2010-09-07 15:03:20
【问题描述】:

我有一个选项卡式 GUI,每个选项卡都包含一个框架。在其中一个框架中有一个 DataGrid。当用户选择此选项卡时,我需要对数据网格进行排序,因此我使用 TabControl SelectionChanged 事件来触发排序。但是,每次从 DataGrid 中选择一个项目时都会触发此事件,即使选项卡本身保持不变。

我尝试了许多不同的事件: TabItem 的 GotFocus 用于 TabItem 的 RequestBringIntoView

但他们似乎都遇到了这个问题。这是什么原因造成的?

【问题讨论】:

    标签: c# wpf tabcontrol tabitem


    【解决方案1】:

    TabControl.SelectionChangedComboBox.SelectionChanged 是同一事件

    源自Selector.SelectionChanged

    因此,如果您没有在事件处理程序中将事件标记为已处理,它会在树中冒泡,并最终到达您的 TabControl,这会导致“触发过于频繁”的问题。

    将您的事件标记为在您的 ComboBox/ListBox/ListView/您在 DataGrid 中使用的任何其他选择器的 SelectionChanged 中处理,如下所示:

    private void MyComboBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        e.Handled = true;
    }
    

    这种不便会消失;)。

    【讨论】:

    • 然后他必须处理他的每个标签页上的每个选择器。只需查看并查看 e.OriginalSource 是否为选项卡控件就容易得多。
    • 没错,但是如果他在选择器完成后将他的事件标记为已处理,它会更清晰。 :)
    • 非常感谢您指出问题。至于解决方案,我最终将“if (e.OriginalSource is System.Windows.Controls.TabControl)”添加到我的 TabControl.SelectionChanged 事件中,这样我就不必为我的 Datagrid 创建事件处理程序了。
    • 仅供参考,如果您遇到这种情况:不要只检查 OriginalSource 的类型 - 检查以确保 OriginalSource 实际上是指您的特定 TabControl:“if (ReferenceEquals(e.OriginalSource, this.myTabControl)” . 如果您不这样做,那么所有子选项卡控件都会激活您的事件处理程序代码。
    • 你确定你没有使用预览事件吗?
    【解决方案2】:
    私人无效tabControlName_SelectionChanged(对象发送者,SelectionChangedEventArgs e) { if (e.Source is TabControl) //如果此事件是从 TabControl 触发的,则输入 { if (tabItemName.IsSelected) { //在这里做你的工作 } } }

    【讨论】:

    • 我在主选项卡控件中使用子选项卡控件,我们可以通过使用此条件if (e.Source is TabControl) 来检查 TabName 吗?
    • 在我看来,你最好检查 e.OriginalSource 而不是 e.Source。
    【解决方案3】:

    如果您在父元素中添加了带有 AddHandler 的处理程序,则所有选择更改都将触发 SelectionChanged 事件。在这种情况下,您可以为您的 TabControl 命名,然后在 EventHandler 中检查 OriginalSource 的名称是否是您的 TabControl 的名称。

    【讨论】:

    • 在 OnSelectedChanged 处理程序中,if (Equals(sender, e.OriginalSource)) { /* do the work */ } 那么所有子事件都不会进入条件块
    【解决方案4】:

    另一个不错的方法是向 tabControl.Items.SelectionChanged 添加一个处理程序:

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
      ItemCollection view = tabControl.Items;
      view.CurrentChanged += new EventHandler(view_CurrentChanged);
    }
    
    void view_CurrentChanged(object sender, EventArgs e)
    {
      throw new NotImplementedException();
    }
    

    也许不是 xamly 的方式,但不那么痛苦,因为它只在更改项目时触发。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-04-02
      • 2019-11-18
      • 1970-01-01
      • 1970-01-01
      • 2021-03-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多