【问题标题】:WPF Cancelling Tab Selection causes Changing event to happen twiceWPF 取消选项卡选择会导致更改事件发生两次
【发布时间】:2015-06-12 04:38:11
【问题描述】:

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

 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 事件再次发生,并且我的弹出消息显示了两次。不仅如此,它在首先将另一个窗口聚焦后第二次显示,然后将焦点放回我的选项卡控件的窗口上。 任何想法为什么会发生这种情况?

--编辑-- 看起来我真的只需要e.Cancel 而不需要再次更新SelectedItem。但是,除非我这样做,否则视觉树不会更新。有什么办法可以确保标签控件的可视化树在e.Cancel 发生后更新,而无需更新SelectedItem?

【问题讨论】:

  • 不是只有e.Cancel=true; 有效吗?
  • 我同意 LPL 关于 e.Cancel 的看法。就个人而言,我不喜欢弹出窗口。另一种方法是验证输入并通过验证显示验证错误。您甚至可以在验证错误时禁用所有其他选项卡。
  • 不幸的是,仅使用 e.Cancel 不起作用,选项卡选择仍然改变:s 看起来这个人有类似的问题:stackoverflow.com/questions/4194290/… 但解决方法对我来说会导致奇怪的行为,因为我如上所述。
  • 另外,我同意弹出窗口并不理想,但这也是询问用户是否要保存更改的地方。
  • 您是否有机会在用户控件中使用“加载”事件?

标签: wpf tabcontrol selectionchanging


【解决方案1】:

是的,这有点奇怪...您可以确定性地取消挂钩并将当前更改的事件处理程序挂钩到选项卡控件上的 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;
        }
    }

我希望这会有所帮助。

【讨论】:

    【解决方案2】:

    这个问题很老,但我现在使用选项卡控件遇到了这个问题。我所做的只是在调用处理程序之前解开它。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-14
      • 2013-03-10
      • 1970-01-01
      相关资源
      最近更新 更多