WPF取消选项卡选择导致更改事件发生两次

时间:2011-10-03 23:26:02

标签: wpf tabcontrol selectionchanging

我正在执行以下操作以防止选项卡选择发生变化:

 tabControl.Items.CurrentChanging += new CurrentChangingEventHandler(Items_CurrentChanging);

 void Items_CurrentChanging(object sender, CurrentChangingEventArgs e)
 {
     if( dataIsInvalid )
     {
          // Show some popup message
          var item = ((ICollectionView)sender).CurrentItem;
          e.Cancel = true;
          tabControl.SelectedItem = item; // !! This causes the CurrentChanging event to happen twice !! 
                                          // But without this the visual tree does not update! :( 
     }
}

然而,我现在看到的问题是上面的最后一行导致第二次发生CurrentChanging事件,并且我的弹出消息显示两次。不仅如此,它在第一次将另一个窗口聚焦后再次显示,然后将焦点放回我的选项卡控件的窗口。 任何想法为什么会发生这种情况?

- EDIT-- 看起来我应该只需要e.Cancel而不需要再次更新SelectedItem。但是,除非我这样做,否则不会更新可视树。有没有什么方法可以确保在e.Cancel发生后更新选项卡控件的可视树,而不必更新SelectedItem

2 个答案:

答案 0 :(得分:2)

是的,这有点奇怪...你可以确定地取消挂钩并挂钩PreviewMouseDown选项卡控件上的当前更改事件处理程序。

并且在CurrentChanging本身解开处理程序,所以这样就不会多次调用它。

    private void MyTabControl_PreviewMouseDown(object sender, MouseButtonEventArgs e)
    {
        var tabControl = sender as TabControl;

        if (tabControl != null)
        {
            var temp = new CurrentChangingEventHandler((sender1, e1) => { });
            var handler = new CurrentChangingEventHandler(
                (sender1, e1) =>
                    {
                        var item = ((ICollectionView) sender1).CurrentItem;
                        if (item != null && dataIsInvalid)
                        {
                            e1.Cancel = true;
                            Dispatcher.BeginInvoke(
                                new Action(() =>
                                   {
                                       tabControl.SelectedItem = item;
                                   }));
                        }

                        tabControl.Items.CurrentChanging -= temp;
                    });

            temp = handler;
            tabControl.Items.CurrentChanging -= handler;
            tabControl.Items.CurrentChanging += handler;
        }
    }

我希望这会有所帮助。

答案 1 :(得分:0)

这个问题已经过时了,但我现在遇到了一个标签控件。在我打电话之前,我所做的就是解开处理程序。

InsturmentTabs.Items.CurrentChanging -= new CurrentChangingEventHandler(Items_CurrentChanging);
InsturmentTabs.Items.CurrentChanging += new CurrentChangingEventHandler(Items_CurrentChanging);

private void Items_CurrentChanging(object sender, CurrentChangingEventArgs e)
    {
        if (condition)
        {
            var item = ((ICollectionView)sender).CurrentItem;
            e.Cancel = true;

            InsturmentTabs.SelectedItem = item;              
        }                                          
    }