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);
}
}