首页 > 解决方案 > 如何在 C# 中遍历 Observable 集合?

问题描述

我有如下所示的以​​下类模型。

 public abstract partial class KeyItemBase : INotifyPropertyChanged
    {
        public KeyItemBase() : this(null, Enumerable.Empty<KeyItemBase>()) { }

        public KeyItemBase(string key, IEnumerable<KeyItemBase> children)
        {
            this.m_key = key;
            this.m_children = new ObservableCollection<KeyItemBase>(children);
        }

        string m_key;
        public string key 
        { 
            get { return m_key; }
            set
            {
                m_key = value;
                RaisedOnPropertyChanged("key");
            }
        }

        ObservableCollection<KeyItemBase> m_children;
        public ObservableCollection<KeyItemBase> Children { get { return m_children; } }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void RaisedOnPropertyChanged(string _PropertyName)
        {
            var changed = PropertyChanged;
            if (changed != null)
            {
                changed(this, new PropertyChangedEventArgs(_PropertyName));
            }
        }
    }

    public abstract partial class KeyItemBase
    {
        // Generate clean JSON on re-serialization.
        public bool ShouldSerializeChildren() { return Children != null && Children.Count > 0; }
    }

    public sealed class KeyItem : KeyItemBase
    {
        // Use for a JSON object with no T_id property.
        // Bind an appropriate SfTreeView.ItemTemplate to this type.

        public KeyItem() : base() { }

        public KeyItem(string key, IEnumerable<KeyItemBase> children) : base(key, children) { }
    }

    public class KeyIdItem : KeyItemBase
    {
        // Use for a JSON object with a T_id property.
        // Bind an appropriate SfTreeView.ItemTemplate to this type.

        public KeyIdItem() : base() { }

        public KeyIdItem(string key, IEnumerable<KeyItemBase> children, long t_id) : base(key, children) { this.m_id = t_id; }

        long m_id;
        public long T_id 
        { 
            get { return m_id; }
            set
            {
                m_id = value;
                RaisedOnPropertyChanged("T_id");
            }
        }
    }

    public static class KeyItemFactory
    {
        public static KeyItemBase ToKeyObject(string name, long? id, IEnumerable<KeyItemBase> children)
        {
            if (id == null)
                return new KeyItem(name, children);
            else
                return new KeyIdItem(name, children, id.Value);
        }

        public static IEnumerable<KeyItemBase> ToKeyObjects(JToken root)
        {
            return root.TopDescendantsWhere<JObject>(o => true)
                .Select(o => ToKeyObject(((JProperty)o.Parent).Name, (long?)o["T_id"], ToKeyObjects(o)));
        }
    }

以下代码行, var items = new ObservableCollection<KeyItemBase>(KeyItemFactory.ToKeyObjects(root));

返回我一个 ObservableCollection 类型的可观察集合。

问题 #1:我希望能够使用 foreach 或任何其他方法进行迭代,以访问每个“m_key”的所有“m_children”。

Output ObservableCollection<KeyObjectBase>: 
[
  {
    "T_id": 0,
    "key": "Soccer",
    "Children": [
      {
        "key": "Clubs",
        "Children": [
          {
            "T_id": 1,
            "key": "ClubA"
          },
          {
            "T_id": 2,
            "key": "ClubB"
          }
        ]
      },
      {
        "key": "Subs",
        "Children": [
          {
            "T_id": 3,
            "key": "SubA",
            "Children": [
              {
                "T_id": 3,
                "key": "SubE"
              }
            ]
          }
        ]
      },
      {
        "key": "Subs_Used",
        "Children": [
          {
            "T_id": 3,
            "key": "SubK"
          }
        ]
      }
    ]
  }
]

问题#2:我的最终目标是根据我拥有的“key”和“Children”信息,以 xamarin 形式创建一个类似于树视图的结构,并且我将逐步进行。

我以为我可以有一个根树视图节点并遍历其子节点,直到将这些子节点添加到根节点,但我无法将这个概念从我的脑海中变成一种可行的方法。如果有人可以帮助我,我将不胜感激。

目前,我有这样的列表,没有可见的文本。

没有文本字段的 TreeView

标签: c#xamarinxamarin.forms

解决方案


这应该访问树中的每个节点

private void RecurseTree(SomeClass node)
{
  // visit each child node of the current node
  foreach(var n in node.Children)
  {
    RecurseTree(n);
  }

  // do any processing on the current node here

}

你通过传入根节点来调用它

RecurseTree(root);

推荐阅读