[英]How to populate a treeview from a list of objects
我在從對象列表填充樹視圖時遇到問題。 我一直在 google 上尋找解決方案,我找到了一些接近我的問題的主題,但沒有一個解決它。
我有一個包含每個對象屬性的列表:名稱和組。
我想像下面一樣填充我的樹視圖:
+---Group 1
| |
| +--------object.Name <--
| +--------object.Name <-- all objects with object.Group = Group 1
| +--------object.Name <--
|
+---Group 2
| |
| +--------object.Name <--
| +--------object.Name <-- all objects with object.Group = Group 2
| +--------object.Name <--
|
等等。
謝謝。
工作得很好,謝謝。 我剛剛在 else 的開頭和結尾添加了幾行,如下所示。
private void PopulateTreeView()
{
ListOfObjectsSorted = ListOfObjects.OrderBy(r => r.Group).ToList();
var topNode = new TreeNode("Select all");
treeView1.Nodes.Add(topNode);
string currentGroup = ListOfObjectsSorted.First().Group;
var treeNodes = new List<TreeNode>();
var childNodes = new List<TreeNode>();
foreach (Object obj in ListOfObjectsSorted )
{
if (currentGroup == rule.Group)
childNodes.Add(new TreeNode(obj.Name));
else
{
if (childNodes.Count > 0)
{
treeNodes.Add(new TreeNode(currentGroup, childNodes.ToArray()));
childNodes = new List<TreeNode>();
}
childNodes.Add(new TreeNode(obj.Name));
currentGroup = obj.Group;
}
}
if (childNodes.Count > 0)
{
treeNodes.Add(new TreeNode(currentGroup, childNodes.ToArray()));
}
treeView1.Nodes[0].Nodes.AddRange(treeNodes.ToArray());
}
您的問題是技術問題還是解決方法? 您可以按 object.Group 排序,然后在每次組更改時創建一個頂級節點。
編輯:下面是一些示例代碼,我尚未對其進行測試,因此將其更多地視為指導:
string currentGroup = null;
List<TreeNode> treeNodes = new List<TreeNode>();
List<TreeNode> childNodes = new List<TreeNode>();
foreach (BusinessObject obj in objectList)
{
if (currentGroup == obj.Group)
childNodes.Add(new TreeNode(obj.Name));
else
{
if (childNodes.Count > 0)
{
treeNodes.Add(new TreeNode(currentGroup, childNodes.ToArray()));
childNodes = new List<TreeNode>();
}
currentGroup = obj.Group;
}
}
if (childNodes.Count > 0)
{
treeNodes.Add(new TreeNode(currentGroup, childNodes.ToArray()));
}
treeView.Nodes.AddRange(treeNodes.ToArray());
這里有一些在 VB 中...
嘗試
Me.Cursor = Cursors.WaitCursor
If rtb.Visible Then line = rtb.Lines
Dim i, j As Integer
Dim myLst As New ListBox
Dim nod0 As New TreeNode
Dim nod1 As New TreeNode
Dim nodGet As New TreeNode
Dim nodSet As New TreeNode
'Aktualna pozicia
If trw.SelectedNode Is Nothing Then
Else
nodGet = trw.SelectedNode
End If
For Each nod0 In trw.Nodes
If nod0.IsExpanded Then
myLst.Items.Add(nod0.Tag)
For Each nod1 In nod0.Nodes
If nod1.IsExpanded Then myLst.Items.Add(nod1.Tag)
Next
End If
Next
Dim cntr() As Integer = {-1, -1, -1}
trw.Nodes.Clear()
trw.ShowPlusMinus = False
trw.ShowRootLines = False
trw.CheckBoxes = False
For i = 0 To UBound(line)
If Mid(line(i), 1, 1) = "\" Then
j = line(i).IndexOf(dod)
If j > 0 Then
s = Mid(line(i), 1, j)
Else
s = line(i)
End If
If Mid(s, 1, 4) = "\\\\" Then
trw.Nodes.Add(Mid(s, 5))
cntr(0) = cntr(0) + 1
cntr(1) = -1
cntr(2) = -1
trw.Nodes(cntr(0)).Tag = s
trw.Nodes(cntr(0)).ImageIndex = 4
trw.Nodes(cntr(0)).SelectedImageIndex = 5
If trw.Nodes(cntr(0)).Tag = nodGet.Tag Then nodSet = trw.Nodes(cntr(0))
Else
If Mid(s, 1, 3) = "\\\" Then
If cntr(0) = -1 Then trw.Nodes.Add("...") : cntr(0) = 0 : cntr(1) = -1
trw.Nodes(cntr(0)).Nodes.Add(Mid(s, 4))
cntr(1) = cntr(1) + 1
cntr(2) = -1
trw.Nodes(cntr(0)).Nodes(cntr(1)).Tag = trw.Nodes(cntr(0)).Tag.ToString & eol & s
trw.Nodes(cntr(0)).Nodes(cntr(1)).ImageIndex = 1
trw.Nodes(cntr(0)).Nodes(cntr(1)).SelectedImageIndex = 2
If trw.Nodes(cntr(0)).Nodes(cntr(1)).Tag = nodGet.Tag Then nodSet = trw.Nodes(cntr(0)).Nodes(cntr(1))
Else
If Mid(s, 1, 2) = "\\" Then
If cntr(0) = -1 Then trw.Nodes.Add("...") : cntr(0) = 0 : cntr(1) = -1
If cntr(1) = -1 Then trw.Nodes(cntr(0)).Nodes.Add("...") : cntr(1) = 0 : cntr(2) = -1
trw.Nodes(cntr(0)).Nodes(cntr(1)).Nodes.Add(Mid(s, 3))
cntr(2) = cntr(2) + 1
trw.Nodes(cntr(0)).Nodes(cntr(1)).Nodes(cntr(2)).Tag = trw.Nodes(cntr(0)).Nodes(cntr(1)).Tag.ToString & eol & s
trw.Nodes(cntr(0)).Nodes(cntr(1)).Nodes(cntr(2)).ImageIndex = 3
trw.Nodes(cntr(0)).Nodes(cntr(1)).Nodes(cntr(2)).SelectedImageIndex = 4
If trw.Nodes(cntr(0)).Nodes(cntr(1)).Nodes(cntr(2)).Tag = nodSet.Tag Then nodSet = trw.Nodes(cntr(0)).Nodes(cntr(1)).Nodes(cntr(2))
End If
End If
End If
End If
Next i
'Navrat na aktualnu poziciu
Application.DoEvents()
For i = 0 To myLst.Items.Count - 1
For Each nod0 In trw.Nodes
If nod0.Tag = myLst.Items(i).ToString Then nod0.Expand()
For Each nod1 In nod0.Nodes
If nod1.Tag = myLst.Items(i).ToString Then nod1.Expand()
Next
Next
Next i
Application.DoEvents()
If nodSet.Tag <> "" Then trw.SelectedNode = nodSet
Catch ex As Exception
MsgBox(ex.ToString, MsgBoxStyle.Exclamation)
Finally
Me.Cursor = Cursors.Default
End Try
5年后……
調用 >> PrintProperties(null, yourObject, 0);
public void PrintProperties(TreeNode parentNode, object obj, int indent)
{
if (obj == null) return;
string indentString = new string(' ', indent);
Type objType = obj.GetType();
PropertyInfo[] properties = objType.GetProperties();
foreach (PropertyInfo property in properties)
{
object propValue = new object();
if (property.CanRead)
propValue = property.GetValue(obj, null);
if (IsSimpleType(property.PropertyType))
{
//Console.WriteLine("{0}{1}:", indentString, property.Name);
if (parentNode != null)
{
parentNode.Nodes.Add(property.Name, property.Name +": " + (propValue != null ? propValue.ToString() : string.Empty));
}
else
{
treeView.Nodes.Add(property.Name, property.Name + ": " + (propValue != null ? propValue.ToString() : string.Empty));
}
}
else if (typeof(IEnumerable).IsAssignableFrom(property.PropertyType))
{
TreeNode node;
if (parentNode != null)
{
node = parentNode.Nodes.Add(property.Name, property.Name);
}
else
{
node = treeView.Nodes.Add(property.Name, property.Name);
}
//Console.WriteLine("{0}{1}:", indentString, property.Name);
IEnumerable enumerable = (IEnumerable)propValue;
foreach (object child in enumerable)
PrintProperties(node, child, indent + 2);
}
else
{
TreeNode node;
if (parentNode != null)
{
node = parentNode.Nodes.Add(property.Name, property.Name);
}
else
{
node = treeView.Nodes.Add(property.Name, property.Name);
}
PrintProperties(node, propValue, indent + 2);
}
}
}
public static bool IsSimpleType(Type type)
{
return
type.IsValueType ||
type.IsPrimitive ||
new Type[]
{
typeof(String),
typeof(Decimal),
typeof(DateTime),
typeof(DateTimeOffset),
typeof(TimeSpan),
typeof(Guid)
}.Contains(type) ||
Convert.GetTypeCode(type) != TypeCode.Object;
}
這是一個基於@PrepucioArgentino 的答案的版本,它可以更好地處理集合中的復雜類型以及結構。 您還可以忽略基於名稱的屬性(在整個結構中)。 但通常你會想在那里傳遞一個空列表。
public static class TreeNodeHelper
{
public static void PrintProperties(TreeNode parentNode, object obj, int indent, TreeView treeView, ICollection<string> ignoredPropertyNames)
{
string indentString = new string(' ', indent); // used for debugging
if (obj == null)
return;
var objType = obj.GetType();
var properties = objType.GetProperties()
.Where(x => !ignoredPropertyNames.Contains(x.Name))
.ToList();
foreach (var property in properties)
{
if (property.Name.ToUpper().Contains("DiagMessage".ToUpper()))
{
// TODO rem test code
}
var propValue = new object();
if (property.CanRead)
propValue = property.GetValue(obj, null);
if (IsSimpleType(property.PropertyType))
{
Debug.WriteLine("{0}{1}:", indentString, property.Name);
if (parentNode != null)
{
parentNode.Nodes.Add(property.Name,
$"{property.Name}: {(propValue != null ? propValue.ToString() : string.Empty)}");
}
else
{
treeView.Nodes.Add(property.Name,
$"{property.Name}: {(propValue != null ? propValue.ToString() : string.Empty)}");
}
}
else if (typeof(IEnumerable).IsAssignableFrom(property.PropertyType))
{
TreeNode collectionRootNode;
if (parentNode != null)
{
collectionRootNode = parentNode.Nodes.Add(property.Name, property.Name);
}
else
{
collectionRootNode = treeView.Nodes.Add(property.Name, property.Name);
}
Debug.WriteLine("{0}{1}:", indentString, property.Name);
var enumerable = (IEnumerable)propValue;
var count = 0;
foreach (var child in enumerable)
{
count++;
if (!IsSimpleType(child.GetType()))
{
var entryRootNode = collectionRootNode.Nodes.Add($"{property.Name}[{count}]",
$"{property.Name}[{count}]");
PrintProperties(entryRootNode, child, indent + 2, treeView, ignoredPropertyNames);
}
else
{
collectionRootNode.Nodes.Add($"{property.Name}[{count}]", $"{property.Name}[{count}]: {child}");
}
}
}
else
{
TreeNode node;
if (parentNode != null)
{
node = parentNode.Nodes.Add(property.Name, property.Name);
}
else
{
node = treeView.Nodes.Add(property.Name, property.Name);
}
PrintProperties(node, propValue, indent + 2, treeView, ignoredPropertyNames);
}
}
}
public static bool IsSimpleType(Type type)
{
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
{
// nullable type, check if the nested type is simple.
return IsSimpleType(type.GetGenericArguments()[0]);
}
return type.IsPrimitive
|| ((IList)new[]
{
// Structs that are 'simple types', expand on this when needed.
typeof(DateTime),
typeof(DateTimeOffset),
typeof(TimeSpan),
typeof(Guid)
}).Contains(type)
|| type.IsEnum
|| type == typeof(string)
|| type == typeof(decimal);
}
}
TreeNodeHelper.PrintProperties(null, firstMotor, 0, treeView1, new List<string>(new[]{ "Creator", "PlcTag", "PlcComponentCreationInfo" }));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.