如何在C#中迭代Observable集合?

时间:2019-06-03 18:22:17

标签: c# xamarin xamarin.forms

我有以下所示的班级模型。

 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:我的最终目标是根据我已经掌握并正在逐步进行的“密钥”和“子项”信息,以xamarin形式创建树状结构。

我以为我可以有一个根树视图节点,然后对其子节点进行迭代,直到将那些子节点添加到根节点中,但是我无法将这个概念付诸实践。如果有人可以帮助我,我将不胜感激。

目前,我有这样的列表,但看不到文本。

TreeView without the text field

1 个答案:

答案 0 :(得分:2)

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

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);