| | |
| | | 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 |
| | |
| | | get => _IsExpanded; |
| | | set |
| | | { |
| | | if (_IsExpanded == value) |
| | | { |
| | | return; |
| | | } |
| | | //if (_IsExpanded == value) |
| | | //{ |
| | | // return; |
| | | //} |
| | | _IsExpanded = value; |
| | | Set("IsExpanded"); |
| | | SetItemsVisible(value); |
| | |
| | | } |
| | | } |
| | | #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; |
| | |
| | | } |
| | | } |
| | | #endregion |
| | | |
| | | /// <summary> |
| | | /// 所有子项数量 |
| | | /// </summary> |
| | | private int allSubCount; |
| | | |
| | | public int AllSubCount |
| | | { |
| | | get { return allSubCount; } |
| | | set { allSubCount = value; } |
| | | } |
| | | |
| | | |
| | | #region 属性 ParentItem |
| | | private TreeItemData _ParentItem = null; |
| | |
| | | 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() |
| | |
| | | string _ItemsPath = ""; |
| | | |
| | | List<TreeItemData> _RootItems = new List<TreeItemData>(); |
| | | List<TreeItemData> levelOneItems = new List<TreeItemData>(); |
| | | |
| | | private PropertyInfo subDataProperty; |
| | | |
| | | #region 属性 UseTree |
| | | private bool _UseTree = true; |
| | |
| | | _UseTree = value; |
| | | } |
| | | } |
| | | |
| | | public List<TreeItemData> RootItems |
| | | { |
| | | get => _RootItems; |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | public TreeItemDataCollection() |
| | |
| | | } |
| | | 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(); |
| | |
| | | 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)) |
| | |
| | | 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); |
| | | } |
| | |
| | | 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++) |
| | | { |
| | |
| | | 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) |
| | | { |
| | |
| | | |
| | | 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; |
| | | } |