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