TabItem在单击放置在其中的任何控件时触发FocusGot事件

时间:2015-01-02 13:46:40

标签: c# wpf tabcontrol tabitem tabview

点击相关标签后,我就会对下面的方法产生影响。

private void Tab1_GotFocus(Object sender, RoutedEventArgs eventArgs) 
{
  DoStuff();
}

但是,我注意到当我点击该标签上的任何控件时,该事件也会被触发。我可以关掉这个行为吗?我能否检测到事件是“真实”还是“只是为了好玩”,可以这么说?

我脑子里的一个小声音告诉我要比较焦点是什么和丢失的东西,如果它是相同(或小孩)的组件,跳过这个方法。但这听起来很奇怪......

private void Tab1_GotFocus(Object sender, RoutedEventArgs eventArgs)
{
  if(sender == eventArgs.OriginalSource)
    DoStuff();
}

相反,我正在尝试使用以下内容。

private void TabControl_OnSelectionChanged(Object sender, SelectionChangedEventArgs eventArgs)
{
  ...
}

然而,由于我在其中所做的事情,它被解雇然后重新开火。 (在更改选择时,我更新其中一个选项卡上包含的数据网格。我怀疑排序和/或过滤可能会导致这些问题。)

这是正确的方法吗?

1 个答案:

答案 0 :(得分:4)

正如评论中所提到的,UIElement.GotFocusSelector.SelectionChanged都是bubbling events,这意味着它们会冒泡视觉树,并且会在每个提升的孩子的父控件上触发事件处理程序这个路由事件。如果发生GotFocus事件,则UIElementSelectionChanged,{ComboBox每个ListBox控件都会触发每个ListViewDataGrid SelectionChanged 1}}或e.OriginalSource

你应该仍然可以处理TabControl事件,只是忽略private void TabControl_OnSelectionChanged( Object sender, SelectionChangedEventArgs eventArgs) { var tabControl = eventArgs.OriginalSource as TabControl; if (tabControl != null) SolveAllProblems(); } 不是TabControl

的所有来电
TabControl

这不是万无一失的,如果你private void TabControl_OnSelectionChanged( Object sender, SelectionChangedEventArgs eventArgs) { if ((eventArgs.OriginalSource as TabControl)?.SelectedItem == TabToBeHandled) SolveAllProblems(); } 为{{1}}的孩子,它仍会被触发。如果它只应该处理特定的选项卡,以下内容就可以了。

{{1}}

请注意.NET的新增功能 - 惊讶的点(合并运算符)。