question

buddingdeveloper-3601 avatar image
buddingdeveloper-3601 asked ·

How to programmatically set selected node of a treeview in 1803 version

I am using a treeview in my uwp project which supports 1803 version. I need to know how to set the selected node of the treeview programmatically. Also it would be helpful if solution is provided in C#. Thanks in advance.

windows-uwpwindows-uwp-xaml
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

PeterFleischer-3316 avatar image
PeterFleischer-3316 answered ·

Hi, try following demo:

XAML:

 <Page
     x:Class="App1.Page06"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:local="using:App06"
     xmlns:i="using:Microsoft.Xaml.Interactivity"
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
     mc:Ignorable="d"
     Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
   <Page.DataContext>
     <local:ViewModel/>
   </Page.DataContext>
   <StackPanel>
     <Button Content="Select Node" Command="{Binding Cmd}"/>
     <TreeView SelectionMode="Multiple" Height="400">
       <i:Interaction.Behaviors>
         <local:TvBehavior/>
       </i:Interaction.Behaviors>
     </TreeView>
   </StackPanel>
 </Page>


and code:

 using Microsoft.Xaml.Interactivity;
 using System;
 using System.Windows.Input;
 using Windows.UI.Xaml;
 using Windows.UI.Xaml.Controls;
    
 namespace App06
 {
   public class ViewModel
   {
     Random rnd = new Random();
    
     public ICommand Cmd
     {
       get => new RelayCommand((state) =>
       {
         var n = TreeV.RootNodes[rnd.Next(0, TreeV.RootNodes.Count)];
         if (rnd.NextDouble() > .5 && n.HasChildren)
         {
           n.IsExpanded = true;
           n = n.Children[rnd.Next(0, n.Children.Count)];
         }
         //TreeV.SelectedNodes.Clear();
         TreeV.SelectedNodes.Add(n);
       });
     }
    
     public TreeView TreeV { get; set; }
    
         internal void LoadTree()
     {
       for (int i = 1; i < 10; i++)
       {
         var n = new TreeViewNode() { Content = $"Node {i}" };
         TreeV.RootNodes.Add(n);
         for (int k = 1; k < 10; k++) n.Children.Add(new TreeViewNode() { Content = $"SubNode {i} {k}" });
       }
     }
   }
    
   public class TvBehavior : Behavior<TreeView>
   {
     protected override void OnAttached() => AssociatedObject.Loaded += AssociatedObject_Loaded;
     private void AssociatedObject_Loaded(object sender, RoutedEventArgs e)
     {
       var vm = AssociatedObject.DataContext as ViewModel;
       if (vm == null) return;
       vm.TreeV = AssociatedObject;
       vm.LoadTree();
     }
   }
    
   public class RelayCommand : ICommand
   {
     private readonly Predicate<object> _canExecute;
     private readonly Action<object> _execute;
     public event EventHandler CanExecuteChanged;
     public RelayCommand(Action<object> execute) : this(execute, null) { }
     public RelayCommand(Action<object> execute, Predicate<object> canExecute) { _execute = execute; _canExecute = canExecute; }
     public bool CanExecute(object parameter) => (_canExecute == null) ? true : _canExecute(parameter);
     public void Execute(object parameter) => _execute(parameter);
     public void RaiseCanExecuteChanged() => CanExecuteChanged?.Invoke(this, EventArgs.Empty);
   }
 }


1 comment Share
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

It worked... Thank you so much!!!

0 Votes 0 · ·
RichardZhang-MSFT avatar image
RichardZhang-MSFT answered ·

Hello,​

Welcome to our Microsoft Q&A platform!

We can usually set TreeView's selected item by binding.

This is a simple idea:

1. Create a data class, which contains a property to control whether it is selected

 public class Model : INotifyPropertyChanged
 {
     public string Name { get; set; }
     public bool _isSelected;
     public bool IsSelected
     {
         get => _isSelected;
         set
         {
             _isSelected = value;
             OnPropertyChanged();
         }
     }
     public List<Model> Children { get; set; }
     public event PropertyChangedEventHandler PropertyChanged;
     public void OnPropertyChanged([CallerMemberName]string propertyName = "")
     {
         PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
     }
 }

2. Create a data collection as a data source

 private ObservableCollection<SupportTopic> TopicCollection = new ObservableCollection<SupportTopic>();


3. Create the corresponding DataTemplate and bind the corresponding properties

 <TreeView x:Name="MyTreeView"
       ItemsSource="{x:Bind TopicCollection}">
     <TreeView.ItemTemplate>
         <DataTemplate x:DataType="local:Model">
             <TreeViewItem Content="{x:Bind Name}"
                           ItemsSource="{x:Bind Children}"
                           IsSelected="{x:Bind IsSelected,Mode=OneWay}"
                           />
         </DataTemplate>
     </TreeView.ItemTemplate>
 </TreeView>



In this case, if you need to set an item in the list as a selected item, you only need to set the corresponding Model.IsSelected to True.

Thanks.

2 comments Share
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi Richard, this code ist not supporten in treeview in 1803 version.

0 Votes 0 · ·

Hi Richard, Thanks for the answer but as Peter said it does not work for 1803.

0 Votes 0 · ·