using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; using System.Linq.Expressions; namespace InABox.Core { public class CoreTreeNode : INotifyPropertyChanged { private CoreTreeNodes _owner; public ObservableCollection> Children => new ObservableCollection>(_owner.GetChildrenOfParent(_id)); private TKey _id; public TKey ID { get { return _id; } set { _id = value; RaisedOnPropertyChanged("ID"); } } private TKey _parent; public TKey Parent { get { return _parent; } set { _parent = value; RaisedOnPropertyChanged("Parent"); } } private object _image; public object Image { get => _image; set { _image = value; RaisedOnPropertyChanged("Image"); } } private CoreRow _row; public CoreRow Row { get => _row; set { _row = value; RaisedOnPropertyChanged("Row"); RaisedOnPropertyChanged("Item[]"); } } public object? this[string column] { get => Row[column]; set { Row[column] = value; _owner.DoColumnChanged(this, column); } } public event PropertyChangedEventHandler? PropertyChanged; public void RaisedOnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } public CoreTreeNode(CoreTreeNodes owner, CoreRow row) { _owner = owner; _row = row; } public CoreTreeNode(CoreTreeNodes owner, TKey id, TKey parent, CoreRow row) : this(owner, row) { _id = id; _parent = parent; } public CoreTreeNode? GetParent() => _owner[_parent]; public int Index() { var parent = GetParent(); return parent != null ? parent.Children.IndexOf(this) + 1 : _owner.Nodes.IndexOf(this) + 1; } public void InvalidateData() { RaisedOnPropertyChanged("Row"); RaisedOnPropertyChanged("Item[]"); } public String Number { get { String result = Index().ToString(); var parent = GetParent(); while (parent != null) { int index = parent.Index(); result = $"{index}.{result}"; parent = parent.GetParent(); } return result; } } } public class CoreTreeNodes where TNode : CoreTreeNode { private List _nodes; private Dictionary _nodeMap; public TKey DefaultKey { get; set; } public ObservableCollection Nodes => new ObservableCollection(_nodes.Where(x => Equals(x.Parent, DefaultKey))); public TNode? this[TKey id] => _nodeMap.GetValueOrDefault(id); public CoreTreeNodes(TKey defaultKey) { _nodes = new List(); _nodeMap = new Dictionary(); DefaultKey = defaultKey; } public TNode Add(TKey id, TKey parent, CoreRow row) { var node = (TNode)Activator.CreateInstance(typeof(TNode), this, id, parent, row ); _nodes.Add(node); _nodeMap[id] = node; return node; } public TNode Find(TKey id) => _nodeMap.GetValueOrDefault(id); public TNode? Find(CoreRow row) => _nodes.FirstOrDefault(x => x.Row == row); /// /// Gets a given node and recursively all its children given by . /// /// /// public IEnumerable GetChildren(TKey id) { if(!_nodeMap.TryGetValue(id, out var node)) { yield break; } yield return node; var children = GetChildrenOfParent(id); foreach (var child in children) foreach (var item in GetChildren(child.ID)) yield return item; } /// /// Get all the direct children of the parent given by . /// /// /// public IEnumerable GetChildrenOfParent(TKey id) { return _nodes.Where(x => object.Equals(x.Parent, id) && !object.Equals(x.ID, id)); } public void Load(CoreTable table, Expression> id, Expression> parentid) { _nodes.Clear(); foreach (var row in table.Rows) { var _id = row.Get(id); var _parent = row.Get(parentid); Add(_id, _parent, row); } } public delegate void ColumnChangedEventHandler(CoreTreeNode node, string column); public event ColumnChangedEventHandler? ColumnChanged; internal void DoColumnChanged(CoreTreeNode node, string column) { ColumnChanged?.Invoke(node, column); } } public class CoreTreeNodes : CoreTreeNodes, TKey> { public CoreTreeNodes(TKey defaultKey) : base(defaultKey) { } } }