开发者

WPF Cancelling Tab Selection causes Changing event to happen twice

开发者 https://www.devze.com 2023-04-10 03:46 出处:网络
I am doing something like the following to prevent a tab selection from changing: tabControl.Items.CurrentChanging += new CurrentChangingEventHandler(Items_CurrentChanging);

I am doing something like the following to prevent a tab selection from changing:

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

 void Items_CurrentChanging(object sender, Cur开发者_如何学JAVArentChangingEventArgs 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! :( 
     }
}

However the problem that I am seeing right now is that the last line above causes a CurrentChanging event to happen a second time, and my popup message is displayed twice. Not only that, it is displayed the second time after bringing another window into focus first, and then putting focus back on my tab control's window. Any ideas why this could be happening?

--EDIT-- It looks like I should really only need e.Cancel and not require updating the SelectedItem again. However the visual tree is not updated unless I do this. Is there any way I can ensure the visual tree of the tab control is updated after e.Cancel occurs, without having to update the SelectedItem?


Yes this is a little wierd... you can deterministically unhook and hook the current changing event handler in the PreviewMouseDown on tab control.

And in CurrentChanging itself unhook the handler so this way it will not be called multiple times atleast.

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

I hope this helps.


This question is old but I just ran into this problem now with a tab control. All I did was unhoook the handler before I called it.

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

精彩评论

暂无评论...
验证码 换一张
取 消