标准的WPF树形视图不支持多选。
我如何为我的WPF应用程序添加支持多选的树形视图?商业产品也可以(我目前知道一个商业实现- http://www.telerik.com/products/wpf/treeview.aspx)
标准的WPF树形视图不支持多选。
我如何为我的WPF应用程序添加支持多选的树形视图?商业产品也可以(我目前知道一个商业实现- http://www.telerik.com/products/wpf/treeview.aspx)
以下代码运行正常且更简单。但缺点是使用了TreeView类的非公共属性IsSelectionChangeActive。代码如下:
private static readonly PropertyInfo IsSelectionChangeActiveProperty
= typeof (TreeView).GetProperty
(
"IsSelectionChangeActive",
BindingFlags.NonPublic | BindingFlags.Instance
);
public static void AllowMultiSelection(TreeView treeView)
{
if (IsSelectionChangeActiveProperty==null) return;
var selectedItems = new List<TreeViewItem>();
treeView.SelectedItemChanged += (a, b) =>
{
var treeViewItem = treeView.SelectedItem as TreeViewItem;
if (treeViewItem == null) return;
// allow multiple selection
// when control key is pressed
if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
{
// suppress selection change notification
// select all selected items
// then restore selection change notifications
var isSelectionChangeActive =
IsSelectionChangeActiveProperty.GetValue(treeView, null);
IsSelectionChangeActiveProperty.SetValue(treeView, true, null);
selectedItems.ForEach(item => item.IsSelected = true);
IsSelectionChangeActiveProperty.SetValue
(
treeView,
isSelectionChangeActive,
null
);
}
else
{
// deselect all selected items except the current one
selectedItems.ForEach(item => item.IsSelected = (item == treeViewItem) );
selectedItems.Clear();
}
if (!selectedItems.Contains(treeViewItem))
{
selectedItems.Add(treeViewItem);
}
else
{
// deselect if already selected
treeViewItem.IsSelected = false;
selectedItems.Remove(treeViewItem);
}
};
}
根据您需要的确切语义,解决方案可能非常简单:
如果您的树的根不是TreeView
,例如如果它是一个普通的ItemsControl
,则树中的所有TreeViewItem都可以独立选择,因此您基本上可以免费获得多选。 因此,只需使用ItemsControl
而不是TreeView
作为您的树的根。
这个解决方案的好处是实现起来非常简单。 它与mattdlong的解决方案不同之处在于:
另一个区别是他的解决方案中键盘导航(箭头键)会取消选择所有项目,而在此解决方案中键盘导航不会取消选择项目。
您应该根据您喜欢的语义(单击添加项目还是ctrl-click添加项目等)在这些解决方案之间进行选择。 如果您想要更高级的语义,例如Shift-Click等,那么相对容易添加。
请注意,您还可以使用ToggleButton
或 CheckBox
在 ItemContainerTemplate
中的任何位置自定义样式 TreeViewItems,并将其设置为 Checked={Binding IsSelected}
。这允许用户通过单击 ToggleButton
或 CheckBox
来选择项目。