2,854 questions
Hi,
Welcome to our Q&A platform!
The reply from Peter Fleischer
you can simplified your code.
- use ObservableCollection instead of list,
- use SelectedItemChanged event to get SelectedItem.
Try following demo. Demo use Interaction and MVVM.
XAML:
<Window x:Class="WpfApp1.Window13"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp13"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
mc:Ignorable="d"
Title="Window13" Height="450" Width="800">
<Window.DataContext>
<local:ViewModel/>
</Window.DataContext>
<StackPanel>
<Button Content="Add new person" Command="{Binding Cmd}"/>
<TreeView ItemsSource="{Binding View}" Margin="5">
<i:Interaction.Behaviors>
<local:TreeViewBehavior/>
</i:Interaction.Behaviors>
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:TreeViewList}"
ItemsSource="{Binding Children}">
<Label Content="{Binding Name}"/>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
</StackPanel>
</Window>
Code:
using System;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interactivity;
namespace WpfApp13
{
public class ViewModel
{
public ObservableCollection<TreeViewList> treelist = new ObservableCollection<TreeViewList>();
public ObservableCollection<TreeViewList> View { get => treelist; }
public TreeViewList SelectedItem { get; set; }
public ICommand Cmd { get => new RelayCommand(AddFolder_Click); }
private int nr = 1;
private TreeViewList person { get => new TreeViewList() { Name = $"Name {nr++}" }; }
private void AddFolder_Click(object state)
{
if (SelectedItem == null) treelist.Add(person); else SelectedItem.Children.Add(person);
}
}
public class TreeViewList
{
public string Name { get; set; }
public ObservableCollection<TreeViewList> Children { get; set; } = new ObservableCollection<TreeViewList>();
}
public class TreeViewBehavior : Behavior<TreeView>
{
protected override void OnAttached()
{
AssociatedObject.SelectedItemChanged += AssociatedObject_SelectedItemChanged;
}
private void AssociatedObject_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
var tv = sender as TreeView;
if (tv == null) return;
var vm = tv.DataContext as ViewModel;
if (vm == null) return;
vm.SelectedItem = tv.SelectedItem as TreeViewList;
}
}
public class RelayCommand : ICommand
{
private readonly Predicate<object> _canExecute;
private readonly Action<object> _action;
public RelayCommand(Action<object> action) { _action = action; _canExecute = null; }
public void Execute(object o) => _action(o);
public bool CanExecute(object o) => _canExecute == null ? true : _canExecute(o);
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
}
}
Thanks.