0

我正在开发 WPF 项目以在TreeView. 我有 propertyPaths(例如:NetworkControl.AlternateIndexText.Value")路径有 id。

树模型

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;

    }
}

起订量一些数据

   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。

4

2 回答 2

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;
}
于 2013-06-11T21:42:31.830 回答
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;
}
于 2013-06-11T21:52:53.113 回答