我正在研究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。
答案 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;
}