| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236 | using System;using System.Collections.Generic;using System.Collections.ObjectModel;using System.ComponentModel;using System.Linq;using System.Linq.Expressions;namespace InABox.Core{    public interface ICoreTreeNode    {        object? ID { get; set; }        object? Parent { get; set; }        object? Image { get; set; }        CoreRow? Row { get; set; }        object? this[string column] { get; set; }        string Number { get; }    }    public class CoreTreeNode<TKey> : INotifyPropertyChanged, ICoreTreeNode    {        private CoreTreeNodes<TKey> _owner;                public ObservableCollection<CoreTreeNode<TKey>> Children => new ObservableCollection<CoreTreeNode<TKey>>(_owner.GetChildrenOfParent(_id));        object? ICoreTreeNode.ID        {            get => ID;            set => ID = (TKey)value!;        }                private TKey _id;        public TKey ID         {            get { return _id; }            set            {                _id = value;                RaisedOnPropertyChanged("ID");            }        }                object? ICoreTreeNode.Parent        {            get => Parent;            set => Parent = (TKey)value!;        }                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<TKey> owner, CoreRow row)        {            _owner = owner;            _row = row;        }        public CoreTreeNode(CoreTreeNodes<TKey> owner, TKey id, TKey parent, CoreRow row) : this(owner, row)        {            _id = id;            _parent = parent;        }        public CoreTreeNode<TKey>? 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<TKey>    {        private List<CoreTreeNode<TKey>> _nodes;        private Dictionary<TKey, CoreTreeNode<TKey>> _nodeMap;                public TKey DefaultKey { get; set; }        public ObservableCollection<CoreTreeNode<TKey>> Nodes { get; } = new ObservableCollection<CoreTreeNode<TKey>>();        public CoreTreeNode<TKey>? this[TKey id] => _nodeMap.GetValueOrDefault(id);                public CoreTreeNodes(TKey defaultKey)        {            _nodes = new List<CoreTreeNode<TKey>>();            _nodeMap = new Dictionary<TKey, CoreTreeNode<TKey>>();            DefaultKey = defaultKey;        }        public CoreTreeNode<TKey> Add(TKey id, TKey parent, CoreRow row)        {            var node = new CoreTreeNode<TKey>(this, id, parent, row);            _nodes.Add(node);            _nodeMap[id] = node;            if(Equals(node.Parent, DefaultKey))            {                Nodes.Add(node);            }            return node;        }        public void Clear()        {            _nodes.Clear();            _nodeMap.Clear();            Nodes.Clear();        }        public CoreTreeNode<TKey> Find(TKey id) => _nodeMap.GetValueOrDefault(id);        public CoreTreeNode<TKey>? Find(CoreRow row) => _nodes.FirstOrDefault(x => x.Row == row);        /// <summary>        /// Gets a given node and recursively all its children given by <paramref name="id"/>.        /// </summary>        /// <param name="id"></param>        /// <returns></returns>        public IEnumerable<CoreTreeNode<TKey>> 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;        }                /// <summary>        /// Get all the direct children of the parent given by <paramref name="id"/>.        /// </summary>        /// <param name="id"></param>        /// <returns></returns>        public IEnumerable<CoreTreeNode<TKey>> GetChildrenOfParent(TKey id)        {            return _nodes.Where(x => object.Equals(x.Parent, id) && !object.Equals(x.ID, id));        }        public void Load<T>(CoreTable table, Expression<Func<T, TKey>> id, Expression<Func<T, TKey>> 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<TKey> node, string column);        public event ColumnChangedEventHandler? ColumnChanged;        internal void DoColumnChanged(CoreTreeNode<TKey> node, string column)        {            ColumnChanged?.Invoke(node, column);        }    }}
 |