Why TabControl.SelectedContent != (TabControl.SelectedItem as TabItem).Content?

限于喜欢 提交于 2019-11-28 01:58:45

问题


The following sample shouldn't beep (in my opinion) but it does. Why? Does that mean the SelectedContent property is useless? Is it a bug in 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();
}

回答1:


I did some testing and found that the SelectedContent property is set after the SelectionChanged Event has been consumed, while the SelectedItem is set before the event is raised.!

Change one of the Grids to a Stackpanel and set a breakpoint on your if clause...




回答2:


It indeed looks like a bug in WPF. See, in this code: http://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/Windows/Controls/TabControl.cs,342 it first calls base.OnSelectionChanged (which raises the SelectionChanged event), then attempts to set the focus to the selected TabItem (which incidentally also fails since the new content is not displayed yet), and only then calls UpdateSelectedContent, which actually sets the SelectedContent to the new value (content of the new tab).

So yes, the SelectionChanged event is kind of useless. A good workaround is to subscribe to when the SelectedContent dependency property value is changed:

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

If you set a breakpoint in OnTabControlSelectedContentChanged you'll notice that it is raised after SelectionChanged, and by that time the content should be updated. Don't forget also to set the focus to the new content manually (since WPF's attempt to set focus fails). To set the focus, might need to do Dispatcher.BeginInvoke as usual.



来源:https://stackoverflow.com/questions/2551792/why-tabcontrol-selectedcontent-tabcontrol-selecteditem-as-tabitem-content

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!