Silverlight Toolkit Bug (发生在 TabControl 里的 TreeView 身上)

描述:

将Microsoft.Windows.Controls.TreeView置入System.Windows.Controls.TabControl中, 并且选中TreeViewItem时, 如果切换TabItem, 你会发现树节点的焦点从选中那一项开始依次向下切换, 直到最末一项, 其中包括已展开的所有条目.

重现:

前端模板:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<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>

后端代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 随便定义一个类用于数据源
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了.

怎么解决呢? 办法有点以暴治暴的感觉, 失去焦点的标签, 如果有内容, 暂时将内容禁用, 当标签获得焦点时再次启用:

1
2
3
4
5
6
7
8
9
10
11
12
13
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;
}
};

打完收工~~~