Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/261.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C#WPF中,为什么我的TabControl';s SelectionChanged事件触发太频繁?_C#_Wpf_Tabcontrol_Tabitem - Fatal编程技术网

在C#WPF中,为什么我的TabControl';s SelectionChanged事件触发太频繁?

在C#WPF中,为什么我的TabControl';s SelectionChanged事件触发太频繁?,c#,wpf,tabcontrol,tabitem,C#,Wpf,Tabcontrol,Tabitem,我有一个选项卡式GUI,每个选项卡都包含一个框架。其中一个框架中有一个数据网格。当用户选择此选项卡时,我需要对datagrid进行排序,因此我使用TabControl SelectionChanged事件触发排序。但是,每次从DataGrid中选择一个项目时都会触发此事件,即使选项卡本身保持不变 我尝试了许多不同的活动: 获取选项卡项的焦点 选项卡项的RequestBringIntoView 但他们似乎都受到这个问题的困扰。这是什么原因造成的?选项卡Control.SelectionChange

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

我尝试了许多不同的活动: 获取选项卡项的焦点 选项卡项的RequestBringIntoView


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

选项卡Control.SelectionChanged与组合框的事件相同。SelectionChanged

它起源于

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

将事件标记为在您的
组合框
/
列表框
/
列表视图
/数据网格中使用的任何其他选择器中处理的事件,如下所示:

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

这种不便也会消失;)

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

另一个好方法是向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();
}
也许这不是最简单的方式,但它的痛苦较小,因为它只在项目发生更改时才会触发

private void tabControlName_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (e.Source is TabControl) //if this event fired from TabControl then enter { if (tabItemName.IsSelected) { //Do your job here } } } 私有无效选项卡ControlName\u SelectionChanged(对象发送者,SelectionChangedEventArgs e) { if(e.Source是TabControl)//如果此事件是从TabControl触发的,则输入 { 如果(tabItemName.IsSelected) { //在这里做你的工作 } } }
然后,他必须处理每个选项卡页面上的每个选择器。查看e.OriginalSource是否是选项卡控件要容易得多。是的,但如果他在完成选择器时将其事件标记为已处理,则会更简洁。:)非常感谢你指出这个问题。至于解决方案,我最后添加了“if(例如,OriginalSource是System.Windows.Controls.TabControl)”到我的TabControl.SelectionChanged事件,这样我就不必为我的Datagrid.FYI创建事件处理程序,如果您遇到以下情况:不要只检查OriginalSource的类型-检查以确保OriginalSource实际引用了特定的TabControl:“if(ReferenceEquals(e.OriginalSource,this.myTabControl)”。如果没有,则所有子选项卡控件都将激活事件处理程序代码。您确定没有使用预览事件吗?我正在主选项卡控件中使用子选项卡控件,如果(例如,源为TabControl),我们是否可以使用此条件
按TabName进行检查
?在我看来,您最好检查e.OriginalSource而不是e.Source。在OnSelectedChanged处理程序中,
如果(等于(sender,e.OriginalSource)){/*执行工作*/}
则所有子事件都不会进入条件块