Silverlight Toolkit Bug (发生在 TabControl 里的 TreeView 身上)
Silverlight描述:
将Microsoft.Windows.Controls.TreeView置入System.Windows.Controls.TabControl中, 并且选中TreeViewItem时, 如果切换TabItem, 你会发现树节点的焦点从选中那一项开始依次向下切换, 直到最末一项, 其中包括已展开的所有条目.
重现:
前端模板:
#!xml
<usercontrol x:class="TreeViewFocus.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:microsoft_windows_controls="clr-namespace:Microsoft.Windows.Controls;assembly=Microsoft.Windows.Controls"
xmlns:system_windows_controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls">
<stackpanel x:name="LayoutRoot" background="White" orientation="Horizontal" margin="16">
<system_windows_controls:tabcontrol x:name="tabcontrol" width="150">
<system_windows_controls:tabitem header="一">
<microsoft_windows_controls:treeview x:name="treeview">
<microsoft_windows_controls:treeview.itemtemplate>
<microsoft_windows_controls:hierarchicaldatatemplate itemssource="{Binding Path=Child}">
<contentcontrol content="{Binding Path=Name}" />
</microsoft_windows_controls:hierarchicaldatatemplate>
</microsoft_windows_controls:treeview.itemtemplate>
</microsoft_windows_controls:treeview>
</system_windows_controls:tabitem>
<system_windows_controls:tabitem header="二">
<textblock text="Look Right :(" fontsize="16" foreground="Red"/>
</system_windows_controls:tabitem>
</system_windows_controls:tabcontrol>
<textbox x:name="textbox"/>
</stackpanel>
</usercontrol>
后端代码:
#!csharp
// 随便定义一个类用于数据源
public class Person
{
public string Name { get; set; }
public ObservableCollection<Person> Child { get; set; }
public override string ToString() { return Name; }
}
public Page()
{
InitializeComponent();
// 随便填充点数据
var source = new ObservableCollection<Person> {
new Person{Name="蓝皮鼠"},
new Person{Name="大脸猫"},
new Person{Name="小头爸爸", Child = new ObservableCollection<Person>{new Person{Name="大头儿子"}}}
};
// 绑定到 TreeView (模板已经设置好了)
treeview.ItemsSource = source;
// 当 TreeView 的选中项发生变化时, 输出到右侧的文本框中.
treeview.SelectedItemChanged += (s, e) =>
{
textbox.Text += e.NewValue == null ? "" : e.NewValue.ToString() + "\n";
};
}
OK, 让我们看看发生了什么(图有些难看…):

标签切换的瞬间, 树像是被一阵风吹过, 焦点从不至下依次选中过, 顺序与按键盘上的TAB键时的情形相似.

我还曾经试过ListBox, 并没有发现这一问题, 可以肯定的说这是个BUG了.
怎么解决呢? 办法有点以暴治暴的感觉, 失去焦点的标签, 如果有内容, 暂时将内容禁用, 当标签获得焦点时再次启用:
#!csharp
tabcontrol.SelectionChanged += (s, e) =>
{
if (e.RemovedItems != null && e.RemovedItems.Count > 0)
{
var tab = e.RemovedItems.Cast<TabItem>().First();
if (tab.Content != null) (tab.Content as Control).IsEnabled = false;
}
if (e.AddedItems != null && e.AddedItems.Count > 0)
{
var tab = e.AddedItems.Cast<TabItem>().First();
if (tab.Content != null) (tab.Content as Control).IsEnabled = true;
}
};
打完收工~~~