2013-06-11 52 views
0

我正在WPF項目上顯示TreeView中的路徑列表。我有propertyPaths(例如:NetworkControl.AlternateIndexText.Value「)路徑已經IDTreeView:如何保留propertypath的Id?

TreeModel的

public class MessageElement 
{ 
    private int id; 
    public string Name { get; set; } 
    public string path { get; set; } 
    public List<MessageElement> Children { get; set; } 
    public List<MessageElement> messageElements { get; set; } 

    public MessageElement() 
    { 
     Children = new List<MessageElement>(); 
     messageElements = new List<MessageElement>(); 
    } 

    public MessageElement(int id, string name, List<MessageElement> children) 
    { 
     this.ID = id; 
     this.Name = name; 
     this.Children = children; 

    } 


    public MessageElement(int id, string path) 
    { 

     this.ID = id; 
     this.path = path; 

    } 
} 

MOQ一些數據

public List<MessageElement> GetRequestTreeNodes() 
    { 

     messageElements.Add(new MessageElement(1, "NetworkControl.AlternateIndexText.Value")); 
     messageElements.Add(new MessageElement(2, "NetworkControl.AddressData.DestinationID")); 
     messageElements.Add(new MessageElement(3, "NetworkControl.AddressData.MessageOriginatorID.Value")); 


     messageElements.Add(new MessageElement(4, "VehicleSummary.VehicleIdentification.IdentificationID.Value")); 
     messageElements.Add(new MessageElement(4, "TitleSummary.JurisdictionTitlingKeyText.Value")); 
     messageElements.Add(new MessageElement(6, "VehicleSummary.VehicleIdentification.IdentificationID.Value")); 

     return messageElements; 

}

遞歸創建樹:。

public List<MessageElement> BuildTree(IEnumerable<MessageElement> messageElements) 
    { 

     return (
      from element in messageElements   // Ex:(1, "NetworkControl.AlternateIndexText.Value") 
      let elementId = element.id      // get id from message element 
      let splitPath = element.path.Split('.') // get path from message element 
      group element by element.path.Split('.')[0] into pathElementGroup 

      select new MessageElement(ID, path) 
      { 
      ID = elementId, ??       // id of each path Ex: 1 => "NetworkControl.AlternateIndexText.Value" 
                 // this is the hardest part I have to reserve each ID that belongs to the path 
                 //Like I showed in the example 

      Name = pathElementGroup.Key,    //name of each tree node to be displayed on tree 
       Children = BuildTree(     //create child from the propertyPath 
       (from propertyPathElement in pathElementGroup 
        where propertyPathElement.path.Length > pathElementGroup.Key.Length + 1 
        select new MessageElement()) 
       .ToList<MessageElement>()) 
      } 
     ); 

    } 


    } 

如何爲每個屬性路徑保留每個ID,用於構建我的樹節點。

回答

0

如果你可以用LINQ做到這一點,它肯定會非常難看。我會建議一個非LINQ的方法。類似下面的代碼。請注意,因爲您僅爲完整路徑提供了一個ID,所以每個非葉片MessageElement的ID都爲0.只有葉片元素被分配了ID。還請注意,可以通過調用AddNode來更改ID,但路徑相同但ID不同。你可能想要解決這個問題。

static class Program 
{ 
    static void Main(string[] args) 
    { 
     var nodes = new List<MessageElement>(); 

     // form 1 
     AddNode(nodes, 1, "NetworkControl.AlternateIndexText.Value"); 
     AddNode(nodes, 2, "NetworkControl.AddressData.DestinationID"); 
     AddNode(nodes, 3, "NetworkControl.AddressData.MessageOriginatorID.Value"); 

     // form 2 
     AddNode(nodes, 4, "VehicleSummary" , "VehicleIdentification", "IdentificationID", "Value"); 
     AddNode(nodes, 4, "TitleSummary", "JurisdictionTitlingKeyText", "Value"); 
     AddNode(nodes, 6, "VehicleSummary", "VehicleIdentification", "IdentificationID", "Value"); 
    } 

    // form 1 
    private static void AddNode(List<MessageElement> nodes, int id, string path) 
    { 
     AddNode(nodes, id, path.Split('.')); 
    } 

    // form 2 
    private static void AddNode(List<MessageElement> nodes, int id, params string[] path) 
    { 
     MessageElement currentNode = null; 
     foreach (var name in path) 
     { 
      var currentCollection = (currentNode != null ? currentNode.Children : nodes); 
      var thisNode = currentCollection.FirstOrDefault(n => n.Name == name); 
      if (thisNode == null) 
      { 
       thisNode = new MessageElement { Name = name }; 
       currentCollection.Add(thisNode); 
      } 
      currentNode = thisNode; 
     } 
     if (currentNode != null) 
      currentNode.ID = id; 
    } 
} 

public class MessageElement 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 
    public List<MessageElement> Children 
    { 
     get { return _children ?? (_children = new List<MessageElement>()); } 
    } 
    private List<MessageElement> _children; 
} 
+0

我調試你的代碼,它表明id被分配給只有最後一個(葉)元素有ID。這就是你所評論的。我想要做的是如何創建一個(Key,Value)對,併爲每個路徑指定指定的ID。例如,如果我想在ID = 1的路徑和ID = 1的網格元素之間創建關係。 –

+0

這是我嘗試過的:http://stackoverflow.com/questions/16993507/wpf-treeview-from-keyvaluepairint-string?noredirect=1#comment24556019_16993507 –

0

這裏有一個LINQ的辦法,做到這一點。它使用Aggregate作爲構建/沿着樹行走的手段。

static class Program 
{ 
    static void Main(string[] args) 
    { 
     var nodes = new List<MessageElement>(); 

     // form 1 
     AddNode(nodes, 1, "NetworkControl.AlternateIndexText.Value"); 
     AddNode(nodes, 2, "NetworkControl.AddressData.DestinationID"); 
     AddNode(nodes, 3, "NetworkControl.AddressData.MessageOriginatorID.Value"); 

     // form 2 
     AddNode(nodes, 4, "VehicleSummary" , "VehicleIdentification", "IdentificationID", "Value"); 
     AddNode(nodes, 4, "TitleSummary", "JurisdictionTitlingKeyText", "Value"); 
     AddNode(nodes, 6, "VehicleSummary", "VehicleIdentification", "IdentificationID", "Value"); 
    } 

    // form 1 
    private static void AddNode(List<MessageElement> nodes, int id, string path) 
    { 
     AddNode(nodes, id, path.Split('.')); 
    } 

    // form 2 
    private static void AddNode(List<MessageElement> nodes, int id, params string[] path) 
    { 
     var finalNode = path.Aggregate<string, MessageElement>(
      null, 
      (currentNode, name) => 
       { 
        var currentCollection = (currentNode != null ? currentNode.Children : nodes); 
        var thisNode = currentCollection.FirstOrDefault(n => n.Name == name); 
        if (thisNode == null) 
        { 
         thisNode = new MessageElement {Name = name}; 
         currentCollection.Add(thisNode); 
        } 
        return thisNode; 
       } 
      ); 
     if (finalNode != null) 
      finalNode.ID = id; 
    } 
} 

public class MessageElement 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 
    public List<MessageElement> Children 
    { 
     get { return _children ?? (_children = new List<MessageElement>()); } 
    } 
    private List<MessageElement> _children; 
}