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