2016-10-21 54 views
2

我創建了一個解析器讀取方式如下格式的文件:TreeView的填充/綁定

version="v4.5.32" 
name="Test File" 
date="2513.04.02" 
players= 
{ 
    { 
     first_name="John" 
     last_name="Smith" 
     country=12 
     id=0 
    } 
    { 
     first_name="Mario" 
     last_name="Rossi" 
     country=56 
     id=1 
    } 
} 
next_player_id=2 
matches= 
{ 
    22 47 88 1045 1048 3511 
} 
settings= 
{ 
    match_prefix="game" 
    match_reward_scalar=1,55 
    match_sets_points= 
    { 
     0,5 0,75 1,0 
    } 
    next_event_id=56 
    next_event_fired=false 
    next_event_probability=0,33 
} 
... 

基本上,這些文件包含鍵/值對的列表,其中鍵始終是一個字符串和值可以是(布爾型,日期型,浮點型,整數型,字符串型),記錄(如settings之類的鍵/值對的子列表)或數組(由簡單值構成,如matchesplayers之類的記錄)。爲了解析和處理這些值,我創建了3個簡單的類。

1)MyPair

public sealed class MyPair 
{ 
    public MyKey Key { get; } 
    public MyValue Value { get; } 

    public MyPair(MyKey key, MyValue value) { ... } 

    public override String ToString() 
    { 
     return String.Concat(Key, " = ", Value); 
    } 
} 

2)的myKey

public sealed class MyKey 
{ 
    public String Name { get; } 
    ... // other properties set by checking the name in the constructor 

    public Key(String name) { ... } 

    public override String ToString() 
    { 
     return Name; 
    } 
} 

3)myvalue的

public sealed class MyValue 
{ 
    private readonly dynamic m_UnderlyingValue; 
    private readonly MyValueCategory m_Category; 

    public dynamic UnderlyingValue 
    { 
     get { return m_UnderlyingValue; } 
    } 

    public Boolean Container 
    { 
     get { return ((m_Category == ValueCategory.Array) || (m_Category == ValueCategory.Record)); } 
    } 

    public MyValueCategory Category 
    { 
     get { return m_Category; } 
    } 

    public MyValue(DateTime underlyingValue) 
    { 
     if (underlyingValue == null) 
      throw new ArgumentNullException("underlyingValue"); 

     m_UnderlyingValue = underlyingValue; 
     m_Category = MyValueCategory.DateTime; 
    } 

    public MyValue(Boolean underlyingValue) { ... } 

    public MyValue(Double underlyingValue) { ... } 

    public MyValue(Int64 underlyingValue) { ... } 

    public MyValue(MyPair[] underlyingValue) { ... } 

    public MyValue(MyValue[] underlyingValue) { ... } 

    public MyValue(String underlyingValue) { ... } 

    public override String ToString() 
    { 
     switch (m_Category) 
     { 
      case MyValueCategory.Array: 
       return String.Concat("Array[", m_UnderlyingValue.Length, "]"); 

      case MyValueCategory.Boolean: 
       return String.Concat("Boolean[", (m_UnderlyingValue ? "true" : "false"), "]"); 

      case MyValueCategory.DateTime: 
       return String.Concat("DateTime[", m_UnderlyingValue.ToString("yyyy.MM.dd", CultureInfo.InvariantCulture), "]"); 

      case MyValueCategory.Float: 
       return String.Concat("Float[", m_UnderlyingValue.ToString("F3", CultureInfo.InvariantCulture), "]"); 

      case MyValueCategory.Integer: 
       return String.Concat("Integer[", m_UnderlyingValue.ToString("F0", CultureInfo.InvariantCulture), "]"); 

      case MyValueCategory.Record: 
       return String.Concat("Record[", m_UnderlyingValue.Length, "]"); 

      default: 
       return String.Concat("Text[", m_UnderlyingValue, "]"); 
     } 
    } 
} 

public enum MyValueCategory 
{ 
    Array, 
    Boolean, 
    DateTime, 
    Float, 
    Integer, 
    Record, 
    Text 
} 

解析過程就像一個魅力,並返回我MyValue實例工作方式類似一個容器/根節點,用於我解析的所有內容。我不使用WPF表格,只是普通的Winforms。我想用分析數據分層填充TreeView控件,然後使這些數據響應對TreeView節點所做的更改。我真的不知道如何將數據綁定到控件本身,並允許鏡像操作。

有什麼建議嗎?

+0

**(1)**''TreeView'不支持數據綁定,您應該手動將節點添加到treeview控件。 **(2)**如果你可以像'XML'或'JSON'或類似'XElement'這樣的有組織的和規則的結構來解析輸入,那麼你可以使用遞歸方法將它加載到'TreeView'中這個'void Populate(TreeNode node,Elements [] elements)'。 **(3)**目前似乎輸入不規則,例如'match_reward_scalar = 1,55'和'match_sets_points = {0,5 0,75 1,0}'是數組,但第一個不是有{},而第二個有。 –

+0

如果有人發佈使用像XML/JSON或其他類似規則結構的答案,可以接受嗎?以下課程並不容易,輸入的文字看起來並不規律。如果不可接受,請考慮發佈[最小,完整和可驗證示例](http://stackoverflow.com/help/mcve) –

回答

3

可以填充你的TreeView遞歸與此代碼:

protected override void OnLoad(EventArgs e) 
{ 
    base.OnLoad(e); 

    MyValue root = new MyParser().Parse("MyFilename.own"); 
    Populate(treeView1.Nodes, root.UnderlyingValue); 
} 

protected void Populate(TreeNodeCollection nodes, IList list) 
{ 
    if(list is MyPair[]) 
    { 
     foreach(MyPair pair in list) 
     { 
      TreeNode node = new TreeNode(); 
      node.Text = pair.ToString(); 
      node.Tag = pair; 
      nodes.Add(node); 

      if(pair.Value.Container) 
       Populate(node.Nodes, (IList)pair.Value.UnderlyingValue); 
     } 
    } 

    if(list is MyValue[]) 
    { 
     foreach(MyValue value in list) 
     { 
      TreeNode node = new TreeNode(); 
      node.Text = value.ToString(); 
      node.Tag = value; 
      nodes.Add(node); 

      if(value.Container) 
       Populate(node.Nodes, (IList)value.UnderlyingValue); 
     } 
    } 
} 

結果看起來那麼像:

Populated TreeView

由於@Reza Aghaei已經提到這是不可能做到這一點通過數據綁定。添加/刪除節點後,您必須手動維護您的列表。將node.Tag設置爲相應的對或值可以讓您輕鬆找到並修改它們。