Выбор вкладки «Отмена WPF» приводит к тому, что событие «Изменение» происходит дважды - PullRequest
2 голосов
/ 04 октября 2011

Я делаю что-то вроде следующего, чтобы предотвратить изменение выбора вкладки:

 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 ]

2 голосов
/ 04 октября 2011

Да, это немного странно ... вы можете определенно отцепить и подключить текущий изменяющий обработчик события в элементе управления 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;
        }
    }

Надеюсь, это поможет.

0 голосов
/ 11 июня 2015

Этот вопрос старый, но я только что столкнулся с этой проблемой с помощью вкладки.Все, что я сделал, это отцепил обработчик, прежде чем я его вызвал.

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