问题
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