alielie
2025-11-24 9211ec11c112e18cd99e77f889a01110a70031ce
HMI.UI/Controls/treegrid/Controls/TreeItemData.cs
@@ -4,8 +4,10 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Windows.Data;
namespace HMI.UI
@@ -32,10 +34,10 @@
            get => _IsExpanded;
            set
            {
                if (_IsExpanded == value)
                {
                    return;
                }
                //if (_IsExpanded == value)
                //{
                //    return;
                //}
                _IsExpanded = value;
                Set("IsExpanded");
                SetItemsVisible(value);
@@ -43,6 +45,84 @@
            }
        }
        #endregion
        #region 属性 IsVisible
        private bool _IsVisible = true;
        public bool IsVisible
        {
            get
            {
                return _IsVisible;
            }
            set
            {
                if (_IsVisible == value)
                {
                    return;
                }
                _IsVisible = value;
                Set("IsVisible");
                SetItemsVisible(value);
                VisibleChange?.Invoke(this, value);
            }
        }
        /// <summary>
        /// 用于展开的可见
        /// </summary>
        /// <param name="visible"></param>
        private void SetItemsVisible(bool visible)
        {
            if (IsExpanded == false || visible == false)
            {
                Items.ForEach(p => p.IsVisible = false);
            }
            else
            {
                Items.ForEach(p => p.IsVisible = true);
            }
        }
        /// <summary>
        /// 设置筛选是否可见,比如筛选name1,则包含name1的数据和其父节点都可见
        /// </summary>
        public bool SelectVisible
        {
            get
            {
                return _IsVisible;
            }
            set
            {
                if (_IsVisible == value)
                {
                    return;
                }
                _IsVisible = value;
                Set("IsVisible");
                SetItemsVisible(value);
            }
        }
        /// <summary>
        /// 用于筛选的可见
        /// </summary>
        /// <param name="visible"></param>
        private void SetSelectVisible(bool visible)
        {
            if (visible)
            {
                ParentItem.SelectVisible = visible;
            }
            Items.ForEach(p => p.IsVisible = visible);
        }
        #endregion
        public void NotifyUI()
        {
            IsExpanded = _IsExpanded;
        }
        #region 属性 Level
        private int _Level = 0;
@@ -107,6 +187,18 @@
            }
        }
        #endregion
        /// <summary>
        /// 所有子项数量
        /// </summary>
        private int allSubCount;
        public int AllSubCount
        {
            get { return allSubCount; }
            set { allSubCount = value; }
        }
        #region 属性 ParentItem
        private TreeItemData _ParentItem = null;
@@ -196,79 +288,6 @@
                Set("IconType");
            }
        }
        #endregion
        #region 属性 IsVisible
        private bool _IsVisible = true;
        public bool IsVisible
        {
            get
            {
                return _IsVisible;
            }
            set
            {
                if (_IsVisible == value)
                {
                    return;
                }
                _IsVisible = value;
                Set("IsVisible");
                SetItemsVisible(value);
                VisibleChange?.Invoke(this, value);
            }
        }
        /// <summary>
        /// 用于展开的可见
        /// </summary>
        /// <param name="visible"></param>
        private void SetItemsVisible(bool visible)
        {
            if (IsExpanded == false || visible == false)
            {
                Items.ForEach(p => p.IsVisible = false);
            }
            else
            {
                Items.ForEach(p => p.IsVisible = true);
            }
        }
        /// <summary>
        /// 设置筛选是否可见,比如筛选name1,则包含name1的数据和其父节点都可见
        /// </summary>
        public bool SelectVisible
        {
            get
            {
                return _IsVisible;
            }
            set
            {
                if (_IsVisible == value)
                {
                    return;
                }
                _IsVisible = value;
                Set("IsVisible");
                SetItemsVisible(value);
            }
        }
        /// <summary>
        /// 用于筛选的可见
        /// </summary>
        /// <param name="visible"></param>
        private void SetSelectVisible(bool visible)
        {
            if (visible)
            {
                ParentItem.SelectVisible = visible;
            }
            Items.ForEach(p => p.IsVisible = visible);
        }
        #endregion
        int GetIconType()
@@ -310,6 +329,9 @@
        string _ItemsPath = "";
        List<TreeItemData> _RootItems = new List<TreeItemData>();
        List<TreeItemData> levelOneItems = new List<TreeItemData>();
        private PropertyInfo subDataProperty;
        #region 属性 UseTree
        private bool _UseTree = true;
@@ -324,6 +346,12 @@
                _UseTree = value;
            }
        }
        public List<TreeItemData> RootItems
        {
            get => _RootItems;
        }
        #endregion
        public TreeItemDataCollection()
@@ -341,15 +369,68 @@
            }
            UseTree = useTree;
            ResetItems();
            //subDataProperty = typeof(T).GetProperty(itemsPath);
        }
        protected override void MoveItem(int oldIndex, int newIndex)
        {
            CheckReentrancy();
            TreeItemData source = base[oldIndex];
            TreeItemData target = base[newIndex];
            newIndex += target.AllSubCount;
            if (newIndex == oldIndex - 1)
            {
                return;
            }
            target = base[newIndex];
            int times = source.AllSubCount;
            if (oldIndex < newIndex)
            {
                base.RemoveItem(oldIndex);
                base.InsertItem(newIndex, source);
                OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
                /// 从上往下拉
                for (int i = 0; i < times; i++)
                {
                    CheckReentrancy();
                    source = base[oldIndex];
                    target = base[newIndex];
                    base.RemoveItem(oldIndex);
                    base.InsertItem(newIndex, source);
                    OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
                }
            }
            else if (oldIndex > newIndex)
            {
                /// 从下往上拉
                base.RemoveItem(oldIndex);
                base.InsertItem(++newIndex, source);
                OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
                //MessageBox.Show($"source: {source.Data} {oldIndex}; target: {target.Data} {newIndex}");
                for (int i = 0; i < times; i++)
                {
                    oldIndex++;
                    newIndex++;
                    CheckReentrancy();
                    source = base[oldIndex];
                    target = base[newIndex];
                    //MessageBox.Show($"source: {source.Data} {oldIndex}; target: {target.Data} {newIndex}");
                    base.RemoveItem(oldIndex);
                    base.InsertItem(newIndex, source);
                    OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
                }
            }
        }
        private void List_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            ResetItems();
            //ResetItems();
        }
        private void ResetItems()
        public void ResetItems()
        {
            CheckReentrancy();
            if (_SourceItems is null)
            {
                ClearAllItems();
@@ -359,7 +440,8 @@
            var items = new List<TreeItemData>();
            _RootItems.Clear();
            var list = this.Items.ToDictionary(l => l.Data);
            Dictionary<dynamic, TreeItemData> list = this.Items.
                ToLookup(t => t.Data, t => t).ToDictionary(t => t.Key, t => t.First());
            foreach (var item in _SourceItems)
            {
                if (list.TryGetValue(item, out var treeItem))
@@ -375,8 +457,9 @@
                treeItem.Level = 0;
                items.Add(treeItem);
                _RootItems.Add(treeItem);
                foreach (var sitem in GetSubItems(treeItem, _ItemsPath, list).ToList())
                var subItems = GetSubItems(treeItem, _ItemsPath, list);
                treeItem.AllSubCount = subItems.Count();
                foreach (var sitem in subItems)
                {
                    items.Add(sitem);
                }
@@ -385,17 +468,20 @@
            ResetSubItems(_RootItems);
            this.Items.Clear();
            if (UseTree)
            {
                _RootItems.ForEach(t => this.Items.Add(t));
            }
            else
            {
                items.ForEach(t => this.Items.Add(t));
            }
            items.ForEach(t => this.Items.Add(t));
            //if (UseTree)
            //{
            //    _RootItems.ForEach(t => this.Items.Add(t));
            //}
            //else
            //{
            //    items.ForEach(t => this.Items.Add(t));
            //}
            OnPropertyChanged(new PropertyChangedEventArgs("Count"));
            OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
        }
        private void ResetSubItems(List<TreeItemData> items)
        public static void ResetSubItems(IList<TreeItemData> items)
        {
            for (int i = 0; i < items.Count; i++)
            {
@@ -410,6 +496,13 @@
            var data = treeItem.Data;
            var p = data.GetType().GetProperty(itemsPath);
            var pvalue = p.GetValue(data, null);
            if (pvalue is INotifyCollectionChanged inc)
            {
                //inc.CollectionChanged -= List_CollectionChanged;
                //inc.CollectionChanged += List_CollectionChanged;
            }
            treeItem.Items.Clear();
            if (pvalue is IEnumerable subItems)
            {
@@ -436,8 +529,9 @@
                    treeItem.Items.Add(subitem);
                    yield return subitem;
                    foreach (var sitem in GetSubItems(subitem, itemsPath, list))
                    var subSub = GetSubItems(subitem, itemsPath, list);
                    subitem.AllSubCount = subSub.Count();
                    foreach (var sitem in subSub)
                    {
                        yield return sitem;
                    }