Почему TabControl.SelectedContent! = (TabControl.SelectedItem as TabItem) .Content? - PullRequest
2 голосов
/ 31 марта 2010

Следующий образец не должен подавать звуковой сигнал (по моему мнению), но он делает Зачем? Означает ли это, что свойство SelectedContent бесполезно? Это ошибка в WPF?

<TabControl SelectionChanged="TabControl_SelectionChanged">
    <TabItem Header="Tab 1">
        <Grid/>
    </TabItem>
    <TabItem Header="Tab 2">
        <Grid/>
    </TabItem>
</TabControl>

void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    var t = sender as TabControl;
    if (t.SelectedContent != (t.SelectedItem as TabItem).Content) Console.Beep();
}

Ответы [ 2 ]

3 голосов
/ 01 апреля 2010

Я провел некоторое тестирование и обнаружил, что свойство SelectedContent установлено после Событие SelectionChanged использовано, в то время как SelectedItem установлено до событие вызвано.!

Измените одну из гридов на панель стека и установите точку останова в предложении if ...

1 голос
/ 01 апреля 2016

Это действительно похоже на ошибку в WPF. Смотрите в этом коде: http://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/Windows/Controls/TabControl.cs,342 сначала он вызывает base.OnSelectionChanged (что вызывает событие SelectionChanged), затем пытается установить фокус на выбранный TabItem (который также случайно не срабатывает, поскольку новый контент еще не отображается), и только затем вызывает UpdateSelectedContent , который фактически устанавливает SelectedContent в новое значение (содержимое новой вкладки).

Так что да, событие SelectionChanged бесполезно. Хороший обходной путь - это подписка при изменении значения свойства зависимости SelectedContent:

var dp = DependencyPropertyDescriptor.FromProperty(TabControl.SelectedContentProperty, typeof(TabControl));
dp.AddValueChanged(tabControl, OnTabControlSelectedContentChanged);

Если вы установите точку останова в OnTabControlSelectedContentChanged, вы заметите, что она повышается после SelectionChanged, и к этому времени содержимое должно быть обновлено. Не забудьте также установить фокус на новый контент вручную (поскольку попытка WPF установить фокус не удалась). Для установки фокуса, возможно, потребуется сделать Dispatcher.BeginInvoke как обычно.

...