Reputation: 3381
I'm attempting to enable a TreeView
control to support multi select.
The very basic flow works, if you select multiple items in the TreeView
while holding down ctrl or shift then it will successfully add those items to a list I have in the view model.
The problem is that when actually clicking on the TreeView
items it will only select one visually i.e. only one item is marked as selected. How can I make it highlight/mark multiple items? I don't understand where this is controlled.
The TreeView
xaml:
<TreeView x:Name="availableColumnsTreeView"
AutomationProperties.AutomationId="availableColumnsTreeView"
x:Uid="availableColumnsTreeView"
SelectedItemChanged="availableColumnsTreeView_SelectedItemChanged"
ItemsSource="{Binding Path=TreeFieldData, Mode=OneWay, Converter={StaticResource SortingConverter}, ConverterParameter='DisplayName.Text'}"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto"
Grid.Row="0">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate x:Uid="HierarchicalDataTemplate_1" ItemsSource="{Binding Path=Children, Mode=OneWay, Converter={StaticResource SortingConverter}, ConverterParameter='DisplayName.Text'}">
<TextBlock x:Uid="TextBlock_1" Text="{Binding DisplayName.Text, Mode=OneWay}" />
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
So "availableColumnsTreeView_SelectedItemChanged" is invoked fine, but I need it to actually highlight the selected items.
EDIT: Please read my question before marking it as a duplicate. I tried to be as specific as possible to what my problem is. I'm not looking for a whole solution for multi select hidden away in some one drive document.
Upvotes: 1
Views: 2403
Reputation: 21999
I'm not sure if I 100% follow you. Could provide a small example please?
Sure.
Here is xaml:
<TreeView ItemsSource="{Binding Items}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Path=Children, Mode=OneWay}">
<CheckBox Content="{Binding Text, Mode=OneWay}" IsChecked="{Binding IsSelected}">
<CheckBox.Style>
<Style TargetType="CheckBox">
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected}" Value="True">
<DataTrigger.Setters>
<Setter Property="Foreground" Value="Red" />
</DataTrigger.Setters>
</DataTrigger>
</Style.Triggers>
</Style>
</CheckBox.Style>
</CheckBox>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
And here is cs:
public class Item : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public string Text { get; set; }
public List<Item> Children { get; set; }
bool _isSelected;
public bool IsSelected
{
get { return _isSelected; }
set
{
_isSelected = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsSelected)));
}
}
public Item(string text)
{
Text = text;
}
}
public partial class MainWindow : Window
{
public List<Item> Items { get; set; } = new List<Item>
{
new Item("1") { Children = new List<Item>
{
new Item("11"),
new Item("12"),
new Item("13"),
}},
new Item("2") { Children = new List<Item>
{
new Item("11"),
new Item("12"),
new Item("13"),
}},
new Item("3"),
};
public MainWindow()
{
InitializeComponent();
DataContext = this;
}
}
I am using CheckBox
to select item (no idea how you do it). If item is selected it has its foreground changed to red via data trigger.
As you can see selection (disregards how you implement it, really, I am using single selection TreeView
) is stored inside items as IsSelected
value. You can traverse hierarchical collection to get a list of selected items (this is called flattering).
Note: IPropertyChanged
, it's required if you plan to set IsSelected
from code-behind (e.g. select all items on button press).
It should be easy to adapt to your case.
Upvotes: 1
Reputation: 169200
How can I make it highlight/mark multiple items? I don't understand where this is controlled.
You define the appearance of a TreeViewItem
container using a TreeViewItem
style. If you add an "IsSelected" property to your data object that keeps track of whether the item is currently selected, you could use a DataTrigger
that binds to this one and provide the highlighting, e.g.:
<TreeView>
<TreeView.Resources>
<Style TargetType="TreeViewItem">
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected}" Value="True">
<Setter Property="Background" Value="Yellow" />
</DataTrigger>
</Style.Triggers>
</Style>
</TreeView.Resources>
...
</TreeView>
Make sure that the data class where the "IsSelected" property is defined implements the INotifyPropertyChanged
interface and that you set this property in your event handler or command.
Upvotes: 1