| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 | 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<CoreTreeNode> Children => new ObservableCollection<CoreTreeNode>(_owner.GetChildrenOfParent(_id));                private Guid _id;        public Guid ID         {            get { return _id; }            set            {                _id = value;                RaisedOnPropertyChanged("ID");            }        }                private Guid _parent;        public Guid 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, Guid id, Guid 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     {        private List<CoreTreeNode> _nodes;        private Dictionary<Guid, CoreTreeNode> _nodeMap;        public ObservableCollection<CoreTreeNode> Nodes => new ObservableCollection<CoreTreeNode>(_nodes.Where(x => x.Parent == Guid.Empty));                public CoreTreeNode? this[Guid id] => _nodes.FirstOrDefault(x => x.ID == id);                public CoreTreeNodes()        {            _nodes = new List<CoreTreeNode>();            _nodeMap = new Dictionary<Guid, CoreTreeNode>();        }        public CoreTreeNode Add(Guid id, Guid parent, CoreRow row)        {            var node = new CoreTreeNode(this, id, parent, row);            _nodes.Add(node);            _nodeMap[id] = node;            return node;        }        public CoreTreeNode Find(Guid id) => _nodeMap.GetValueOrDefault(id);        public CoreTreeNode? 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> GetChildren(Guid 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> GetChildrenOfParent(Guid id)        {            return _nodes.Where(x => x.Parent.Equals(id) && (x.ID != id));        }        public void Load<T>(CoreTable table, Expression<Func<T, Guid>> id, Expression<Func<T, Guid>> 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);        }    }}
 |