using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Reactive; using Avalonia.Controls; using ReactiveUI; namespace ControlCatalog.ViewModels { public class TreeViewPageViewModel : ReactiveObject { private readonly Node _root; private SelectionMode _selectionMode; public TreeViewPageViewModel() { _root = new Node(); Items = _root.Children; Selection = new SelectionModel(); Selection.SelectionChanged += SelectionChanged; AddItemCommand = ReactiveCommand.Create(AddItem); RemoveItemCommand = ReactiveCommand.Create(RemoveItem); } public ObservableCollection Items { get; } public SelectionModel Selection { get; } public ReactiveCommand AddItemCommand { get; } public ReactiveCommand RemoveItemCommand { get; } public SelectionMode SelectionMode { get => _selectionMode; set { Selection.ClearSelection(); this.RaiseAndSetIfChanged(ref _selectionMode, value); } } private void AddItem() { var parentItem = Selection.SelectedItems.Count > 0 ? (Node)Selection.SelectedItems[0] : _root; parentItem.AddItem(); } private void RemoveItem() { while (Selection.SelectedItems.Count > 0) { Node lastItem = (Node)Selection.SelectedItems[0]; RecursiveRemove(Items, lastItem); Selection.DeselectAt(Selection.SelectedIndices[0]); } bool RecursiveRemove(ObservableCollection items, Node selectedItem) { if (items.Remove(selectedItem)) { return true; } foreach (Node item in items) { if (item.AreChildrenInitialized && RecursiveRemove(item.Children, selectedItem)) { return true; } } return false; } } private void SelectionChanged(object sender, SelectionModelSelectionChangedEventArgs e) { var selected = string.Join(",", e.SelectedIndices); var deselected = string.Join(",", e.DeselectedIndices); System.Diagnostics.Debug.WriteLine($"Selected '{selected}', Deselected '{deselected}'"); } public class Node { private ObservableCollection _children; private int _childIndex = 10; public Node() { Header = "Item"; } public Node(Node parent, int index) { Parent = parent; Header = parent.Header + ' ' + index; } public Node Parent { get; } public string Header { get; } public bool AreChildrenInitialized => _children != null; public ObservableCollection Children => _children ??= CreateChildren(); public void AddItem() => Children.Add(new Node(this, _childIndex++)); public void RemoveItem(Node child) => Children.Remove(child); public override string ToString() => Header; private ObservableCollection CreateChildren() { return new ObservableCollection( Enumerable.Range(0, 10).Select(i => new Node(this, i))); } } } }