How to Programmatically Select an Item in a Wpf Treeview

How to programmatically select an item in a WPF TreeView?

It's a real pain for some strange reason, you have to use ContainerFromItem to get the container, then invoke the select method.

//  selectedItemObject is not a TreeViewItem, but an item from the collection that 
// populated the TreeView.

var tvi = treeView.ItemContainerGenerator.ContainerFromItem(selectedItemObject)
as TreeViewItem;

if (tvi != null)
{
tvi.IsSelected = true;
}

There once was a blog entry on how to do it here, but the link is dead now.

How to select TreeView item from code

Another option would be to use binding. If you have an object that you are using binding with to get the text of each TreeViewItem (for example), you can create a style that also binds the IsSelected property:

<TreeView>
<TreeView.Resources>
<Style TargetType="TreeViewItem">
<Setter Property="IsSelected"
Value="{Binding Path=IsSelected, Mode=TwoWay}" />
</Style>
</TreeView.Resources>
</TreeView>

This assumes that the bound object has an IsSelected property of type bool. You can then select a TreeViewItem by setting IsSelected to true for its corresponding object.

The same approach can be used with the IsExpanded property to control when a TreeViewItem is expanded or collapsed.

MVVM selecting a treeview item programmatically

When thinking about this. You should really build a wrapper for every element of the tree view that has the IsSelected bool on it as well as the IsExpanded bool they make life so much easier for displaying the data. You could even just add them to your class and use them from there.

Programmatically select a specific TreeViewItem into an unbound TreeView

Set property IsSelected inside of Dispatcher.BeginInvoke.

Programatically select first item in a UWP TreeView

If you edit the TreView's style, you could find that in its ControlTemplate, it actually uses a TreeViewList control.

<Style x:Key="TreeViewStyle1" TargetType="TreeView">
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="CanDragItems" Value="True"/>
<Setter Property="CanReorderItems" Value="True"/>
<Setter Property="AllowDrop" Value="True"/>
<Setter Property="ItemContainerTransitions">
<Setter.Value>
<TransitionCollection>
<ContentThemeTransition/>
<ReorderThemeTransition/>
<EntranceThemeTransition IsStaggeringEnabled="False"/>
</TransitionCollection>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TreeView">
<TreeViewList x:Name="ListControl" AllowDrop="{TemplateBinding AllowDrop}" CanReorderItems="{TemplateBinding CanReorderItems}" CanDragItems="{TemplateBinding CanDragItems}" ItemContainerStyleSelector="{TemplateBinding ItemContainerStyleSelector}" ItemContainerStyle="{TemplateBinding ItemContainerStyle}" ItemTemplate="{TemplateBinding ItemTemplate}" ItemContainerTransitions="{TemplateBinding ItemContainerTransitions}" ItemTemplateSelector="{TemplateBinding ItemTemplateSelector}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

The TreeViewList class inherits from ListView. The ListView has SelectedItem property.

So, you could make a custom TreeView control which inherits TreeView class. Then, you could find the TreeViewList control by calling its GetTemplateChild() method. After that, you could set the selectedItem for it.

Please check my code sample:

public class MyTreeView:TreeView
{
TreeViewList treeViewList;
public MyTreeView()
{
this.Loaded += MyTreeView_Loaded;
}

private void MyTreeView_Loaded(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
if (treeViewList != null)
{
treeViewList.SelectedIndex = 0;
}
}

protected override void OnApplyTemplate()
{
base.OnApplyTemplate();
treeViewList = this.GetTemplateChild("ListControl") as TreeViewList;
}
}

But with this way, you could only set the selectedItem for the RootNodes. If you want to selecte the sub node, I still think the binding on the IsSelected property is the better way.

select a new treeViewItem after insertion in WPF

You need to define a IsSelected property in your viewmodel and call OnPropertyChanged when the property is set.
To link IsSelected to your TreeViewItem define an ItemContainerStyle, for instance in your Resources or directly in your TreeView.

  <TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontWeight" Value="Bold" />
</Trigger>
</Style.Triggers>
</Style>
</TreeView.ItemContainerStyle>

Once you accomplished with that, just set _model.IsSelected = true

In WPF, how do you programmatically deselect all Items in a Treeview?

Each TreeViewItem is a Mini-TreeView. You got the wrong impression or you read something wrong about TreeViewItems.

What you doing wrong is passing the Items collection which doesnt contain children of type TreeViewItem but instead those are the data items.

Pass the children collection and you should do fine.

Like this:

public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();

}

private bool @switch = false;

private void TreeViewDeselectAll(IEnumerable myTreeViewItems, bool value)
{
if (myTreeViewItems != null)
{
foreach (var currentItem in myTreeViewItems)
{
if (currentItem is TreeViewItem)
{
TreeViewItem item = (TreeViewItem)currentItem;
item.IsSelected = value;
if (item.HasItems)
{
TreeViewDeselectAll(LogicalTreeHelper.GetChildren(item), value);
}
}
}
}
}

private void Button_Click(object sender, RoutedEventArgs e)
{
this.TreeViewDeselectAll(LogicalTreeHelper.GetChildren(this.treeView), this.@switch);
}
}

XAML would look like this for example:

<StackPanel>
<TreeView Name="treeView">
<TreeViewItem Header="First Level">
<TreeViewItem Header="Second Level"/>
</TreeViewItem>
</TreeView>
<Button Click="Button_Click">select/unselect all</Button>
</StackPanel>

I changed your TreeViewDeselectAll method a little bit. Based on switch you can select or unselect all.



Related Topics



Leave a reply



Submit