在c# WPF中,为什么我的TabControl的选择更改事件频繁触发?

时间:2021-04-29 23:59:39

I have a tabbed GUI with each tab containing a Frame. In one of these Frames there is a DataGrid. When the user selects this tab, I need my datagrid sorted, so I'm using the TabControl SelectionChanged event to trigger the sort. However, this event triggers every time an item is selected from the DataGrid, even though the tabs themselves remain untouched.

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

I've tried number of different events: GotFocus for a TabItem RequestBringIntoView for a TabItem

我已经尝试了许多不同的事件:GotFocus为一个TabItem请求,以查看一个表项。

but they all seem to suffer from this problem. What is causing this?

但他们似乎都受到这个问题的困扰。是什么原因导致了晒伤的?

4 个解决方案

#1


80  

The TabControl.SelectionChanged is the same event as a ComboBox.SelectionChanged

TabControl。SelectionChanged是与ComboBox.SelectionChanged相同的事件

It originates from Selector.SelectionChanged.

它源于Selector.SelectionChanged。

So, if you do not mark your event as handled in your event handler, it will bubble up the tree, and eventually arrive at your TabControl, which is causing this "firing too often" issue.

因此,如果您不将事件标记为在事件处理程序中处理的事件,那么它将向上冒泡,并最终到达您的TabControl,这将导致“频繁触发”问题。

Mark your event as handled in your SelectionChanged of your ComboBox/ListBox/ListView/any other Selector you use in your DataGrid like so:

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

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

And this inconvenience will go away ;).

这种不方便将会消失。

#2


23  

     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
                }
            }
        }

#3


2  

If you have added a handler with AddHandler in a parent element, all selection changes will fire the SelectionChanged-event. In this case, you can give your TabControl a name and then check in the EventHandler if the name of the OriginalSource is the name of your TabControl.

如果在父元素中添加了带有AddHandler的处理程序,那么所有的选择更改都会触发selectionchanged事件。在这种情况下,您可以给您的TabControl一个名称,然后在EventHandler中检查,如果源源的名称是您的表控件的名称。

#4


2  

Another good approch is adding a handler to the 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();
}

Maybe is not the xamly way, but is less pain as it only fires when an item is changed.

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

#1


80  

The TabControl.SelectionChanged is the same event as a ComboBox.SelectionChanged

TabControl。SelectionChanged是与ComboBox.SelectionChanged相同的事件

It originates from Selector.SelectionChanged.

它源于Selector.SelectionChanged。

So, if you do not mark your event as handled in your event handler, it will bubble up the tree, and eventually arrive at your TabControl, which is causing this "firing too often" issue.

因此,如果您不将事件标记为在事件处理程序中处理的事件,那么它将向上冒泡,并最终到达您的TabControl,这将导致“频繁触发”问题。

Mark your event as handled in your SelectionChanged of your ComboBox/ListBox/ListView/any other Selector you use in your DataGrid like so:

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

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

And this inconvenience will go away ;).

这种不方便将会消失。

#2


23  

     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
                }
            }
        }

#3


2  

If you have added a handler with AddHandler in a parent element, all selection changes will fire the SelectionChanged-event. In this case, you can give your TabControl a name and then check in the EventHandler if the name of the OriginalSource is the name of your TabControl.

如果在父元素中添加了带有AddHandler的处理程序,那么所有的选择更改都会触发selectionchanged事件。在这种情况下,您可以给您的TabControl一个名称,然后在EventHandler中检查,如果源源的名称是您的表控件的名称。

#4


2  

Another good approch is adding a handler to the 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();
}

Maybe is not the xamly way, but is less pain as it only fires when an item is changed.

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