The standard WPF tree view does not support multiple selections.
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)
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:
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);
}
};
}
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.
This solution has the benefit of being extraordinarily simple to implement. It differs from mattdlong's solution in that:
- 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.
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.
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
.
来源:https://stackoverflow.com/questions/1163801/wpf-treeview-with-multiple-selection