I try to apply MVVM for treeview by refer to Josh's tutorial https://www.codeproject.com/Articles/26288/Simplifying-the-WPF-TreeView-by-Using-the-ViewMode
Here is my full source code
TreeNode.cs
public class TreeNode
{
private ObservableCollection<TreeNode> _children = new ObservableCollection<TreeNode>();
public ObservableCollection<TreeNode> Children
{
get { return _children; }
set { _children = value; }
}
public string Name { get; set; }
public string ID { get; set; }
}
TreeNodeViewModel.cs
public class TreeNodeViewModel : INotifyPropertyChanged
{
private ObservableCollection<TreeNodeViewModel> _children;
private TreeNodeViewModel _seletected;
private TreeNodeViewModel _parent;
private TreeNode _node;
bool _isExpanded;
bool _isSelected;
public TreeNodeViewModel(TreeNode node)
: this(node, null)
{
}
private TreeNodeViewModel(TreeNode node, TreeNodeViewModel parent)
{
_node = node;
_parent = parent;
_children = new ObservableCollection<TreeNodeViewModel>(
(from child in _node.Children
select new TreeNodeViewModel(child, this))
.ToList<TreeNodeViewModel>());
}
public ObservableCollection<TreeNodeViewModel> Children
{
get { return _children; }
set { _children = value; }
}
public string Name
{
get { return _node.Name; }
set { _node.Name = value; }
}
public TreeNodeViewModel Selected
{
get { return _seletected; }
set { _seletected = value; }
}
public bool IsExpanded
{
get { return _isExpanded; }
set
{
if (value != _isExpanded)
{
_isExpanded = value;
this.OnPropertyChanged("IsExpanded");
}
// Expand all the way up to the root.
if (_isExpanded && _parent != null)
_parent.IsExpanded = true;
}
}
public bool IsSelected
{
get { return _isSelected; }
set
{
if (value != _isSelected)
{
_isSelected = value;
this.OnPropertyChanged("IsSelected");
if (_isSelected) { _seletected = this; }
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
TreeViewViewModel.cs
public class TreeViewViewModel
{
readonly ObservableCollection<TreeNodeViewModel> _firstLevel;
readonly TreeNodeViewModel _rootNode;
private ICommand _addCommand;
public TreeViewViewModel(TreeNode rootNode)
{
_rootNode = new TreeNodeViewModel(rootNode);
_firstLevel = new ObservableCollection<TreeNodeViewModel>(_rootNode.Children);
_addCommand = new AddCommand(this);
}
public ObservableCollection<TreeNodeViewModel> FirstLevel
{
get { return _firstLevel; }
}
public ICommand AddCommand
{
get { return _addCommand; }
}
}
AddCommand.cs
public class AddCommand : ICommand
{
private TreeViewViewModel _TreeView;
public AddCommand(TreeViewViewModel treeView)
{
_TreeView = treeView;
}
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
//Show Selected item ????
MessageBox.Show(_TreeView.????);
}
}
My goal is when I click to add command, It will show selected item name and parent selected item name. But the problem is there is no anything in TreeViewViewModel to access to TreeNodeViewModel.
It's was prevent by middle class TreeViewViewModel to access to TreeNodeViewModel's property when live in Josh's world