TreeView:如何保留属性路径的ID?

时间:2013-06-11 19:41:30

标签: wpf tree

我正在研究WPF项目,以显示TreeView中的路径列表。我有propertyPaths(例如:NetworkControl.AlternateIndexText.Value“)路径有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。

2 个答案:

答案 0 :(得分:0)

如果你能用LINQ做到这一点,肯定会非常难看。我建议使用非LINQ方法。类似下面的代码。请注意,因为您仅为完整路径提供ID,所以每个非叶MessageElement的ID都为0.仅为叶元素分配ID。另请注意,可以通过使用相同路径但不同ID调用AddNode来更改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;
}

答案 1 :(得分: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;
}