8

我在从对象列表中填充树视图时遇到问题。我一直在谷歌上寻找解决方案,我发现了一些与我的问题很接近的话题,但没有一个能解决它。

我有一个包含每个对象属性的列表:名称和组。

我想填充我的树视图,如下所示:

+---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 <--
|

等等。

谢谢。

4

5 回答 5

3

工作得很好,谢谢。我刚刚在 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());
    }
于 2013-05-06T11:46:14.920 回答
2

您的问题是技术问题,还是只是如何解决?您可以按 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());
于 2013-05-03T09:34:54.740 回答
1

这里有一些在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
于 2014-02-02T06:23:51.277 回答
0

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;
    }
于 2018-09-21T19:53:31.557 回答
0

这是一个基于@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" }));
于 2020-08-18T15:58:18.767 回答