具有多项选择的 WPF TreeView
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1163801/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF TreeView with Multiple Selection
提问by mark
The standard WPF tree viewdoes not support multiple selections.
标准 WPF树视图不支持多选。
How can I add a tree view that supports multiple selection to my WPF application? Commercial products are fine (I am currently aware of one commercial implementation - http://www.telerik.com/products/wpf/treeview.aspx)
如何将支持多选的树视图添加到我的 WPF 应用程序?商业产品很好(我目前知道一种商业实现 - http://www.telerik.com/products/wpf/treeview.aspx)
回答by Kess
The code below works fine and is much simpler. However the draw back is the use of the non public property, IsSelectionChangeActive, of the treeview class. Code below:
下面的代码工作正常,而且更简单。然而,缺点是使用了树视图类的非公共属性 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);
}
};
}
回答by Ray Burns
Depending on the exact semantics you desire, the solution may be extremely simple:
根据您想要的确切语义,解决方案可能非常简单:
If the root of your tree is anything but a TreeView
-- for example if it is a plain ItemsControl
-- all TreeViewItems in the tree will be independently selectatble so you basically get mulitiselect for free. So just use an ItemsControl
instead of a TreeView
for the root of your tree.
如果你的树的根不是一个TreeView
——例如,如果它是一个普通的ItemsControl
——树中的所有 TreeViewItems 将是独立的 selectatble,所以你基本上可以免费获得 multiselect。因此,只需对树的根使用 aItemsControl
而不是 a TreeView
。
This solution has the benefit of being extraordinarily simple to implement. It differs from mattdlong's solution in that:
该解决方案的优点是实施起来非常简单。它与 mattdlong 的解决方案的不同之处在于:
- His solution deselects all other items when an item is clicked, so you have to ctrl-click items to multiselect.
- With this solution a single click will select/deselect the item you clicked on, but there is no way to quickly select an item and simultaneously deselect all others.
- 他的解决方案在单击某个项目时取消选择所有其他项目,因此您必须按住 ctrl 单击项目才能进行多选。
- 使用此解决方案,单击将选择/取消选择您单击的项目,但无法快速选择一个项目并同时取消选择所有其他项目。
Another difference is that keyboard navigation (arrow keys) in his solution deselects all items, whereas in this solution keyboard navigation does not deselect items.
另一个区别是他的解决方案中的键盘导航(箭头键)会取消选择所有项目,而在此解决方案中,键盘导航不会取消选择项目。
You should choose between these solutions based on the semantics you prefer (single click to add item vs ctrl-click to add item, etc). If you want more advanced semantics, such as Shift-Click, etc, it is relatively to add.
您应该根据您喜欢的语义在这些解决方案之间进行选择(单击添加项目与按住 ctrl 单击添加项目等)。如果想要更高级的语义,比如 Shift-Click 等,就比较添加了。
Note that you can also custom style TreeViewItems using a ToggleButton
or CheckBox
anywhere in the ItemContainerTemplate
that has Checked={Binding IsSelected}
. This allows the user to select items by clicking on the ToggleButton
or CheckBox
.
请注意,您还可以使用ToggleButton
或CheckBox
中ItemContainerTemplate
具有Checked={Binding IsSelected}
. 这允许用户通过单击ToggleButton
或来选择项目CheckBox
。