为什么选择TabControl.SelectedContent!=(TabControl.SelectedItem为TabItem).Content?

时间:2010-03-31 09:35:59

标签: wpf tabcontrol

以下示例不应发出哔哔声(在我看来),但确实如此。为什么?这是否意味着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 个答案:

答案 0 :(得分:3)

我做了一些测试,发现在使用了SelectionChanged事件后,SelectedContent属性设置为,而在事件被引发之前将设置为

将其中一个网格更改为Stackpanel并在if子句上设置断点...

答案 1 :(得分:1)

它确实看起来像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