Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将泛型对象绑定到WPF TreeView的数据?_C#_Wpf_Treeview - Fatal编程技术网

C# 将泛型对象绑定到WPF TreeView的数据?

C# 将泛型对象绑定到WPF TreeView的数据?,c#,wpf,treeview,C#,Wpf,Treeview,我有一个反序列化为对象的XML文件,现在我想在WPF树视图中显示该对象。我一直在使用WPF TreeView查找数据绑定,但我一直无法找到我要查找的内容 有没有一种方法可以让WPF TreeView在不事先知道对象结构的情况下显示对象及其子对象?您必须为所有可能的类型提供分层数据模板。假设您的对象看起来像: Entity A Entity B Entity C Entity C Entity B En

我有一个反序列化为对象的XML文件,现在我想在WPF树视图中显示该对象。我一直在使用WPF TreeView查找数据绑定,但我一直无法找到我要查找的内容


有没有一种方法可以让WPF TreeView在不事先知道对象结构的情况下显示对象及其子对象?

您必须为所有可能的类型提供分层数据模板。

假设您的对象看起来像:

    Entity A
        Entity B
            Entity C
            Entity C
        Entity B
    Entity D
        <!-- entity a-->
        <HierarchicalDataTemplate DataType="{x:Type local:EntityA}" ItemsSource="{Binding Items, Mode=OneWay}">
            <StackPanel>
              <!-- your content >
            </StackPanel>
        </HierarchicalDataTemplate>
        <!-- entity b -->
        <HierarchicalDataTemplate DataType="{x:Type local:EntityB}" ItemsSource="{Binding Items, Mode=OneWay}">
            <StackPanel>
              <!-- your content >
            </StackPanel>
        </HierarchicalDataTemplate>
        <!-- entity c -->
        <DataTemplate DataType="{x:Type local:EntityC}">
            <StackPanel>
              <!-- your content >
            </StackPanel>
        </DataTemplate>
        <!-- entity d -->
        <DataTemplate DataType="{x:Type local:EntityD}">
            <StackPanel>
              <!-- your content >
            </StackPanel>
        </DataTemplate>
为每个非叶实体创建分层数据模板,并为每个叶实体创建数据模板

我发现,如果在对象中的每个级别上都有一个ObservableCollection(称为类似项的东西),并且包含下面任何类型的子级,那么很容易适应任何类型的混合层次结构

使用此设置,模板将类似于:

    Entity A
        Entity B
            Entity C
            Entity C
        Entity B
    Entity D
        <!-- entity a-->
        <HierarchicalDataTemplate DataType="{x:Type local:EntityA}" ItemsSource="{Binding Items, Mode=OneWay}">
            <StackPanel>
              <!-- your content >
            </StackPanel>
        </HierarchicalDataTemplate>
        <!-- entity b -->
        <HierarchicalDataTemplate DataType="{x:Type local:EntityB}" ItemsSource="{Binding Items, Mode=OneWay}">
            <StackPanel>
              <!-- your content >
            </StackPanel>
        </HierarchicalDataTemplate>
        <!-- entity c -->
        <DataTemplate DataType="{x:Type local:EntityC}">
            <StackPanel>
              <!-- your content >
            </StackPanel>
        </DataTemplate>
        <!-- entity d -->
        <DataTemplate DataType="{x:Type local:EntityD}">
            <StackPanel>
              <!-- your content >
            </StackPanel>
        </DataTemplate>


我不知道您会找到一个干净的数据绑定解决方案,允许忽略对象,但考虑到您最初从XML反序列化,您可能可以序列化回XML。在这种情况下,您可以在treeview控件中显示XML序列化数据:

从文章中:

在Form1.vb文件中,将“Windows窗体设计器生成的代码”部分后的整个代码替换为以下示例代码:

 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
      ' Initialize the controls and the form.
      Label1.Text = "File Path"
      Label1.SetBounds(8, 8, 50, 20)
      TextBox1.Text = Application.StartupPath() & "\Sample.xml"
      TextBox1.SetBounds(64, 8, 256, 20)
      Button1.Text = "Populate the TreeView with XML"
      Button1.SetBounds(8, 40, 200, 20)
      Me.Text = "TreeView control from XML"
      Me.Width = 336
      Me.Height = 368
      TreeView1.SetBounds(8, 72, 312, 264)
   End Sub

   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
      Try
         ' SECTION 1. Create a DOM Document and load the XML data into it.
         Dim dom As New XmlDocument()
         dom.Load(TextBox1.Text)

         ' SECTION 2. Initialize the treeview control.
         TreeView1.Nodes.Clear()
         TreeView1.Nodes.Add(New TreeNode(dom.DocumentElement.Name))
         Dim tNode As New TreeNode()
         tNode = TreeView1.Nodes(0)

         ' SECTION 3. Populate the TreeView with the DOM nodes.
         AddNode(dom.DocumentElement, tNode)
         TreeView1.ExpandAll()

      Catch xmlEx As XmlException
         MessageBox.Show(xmlEx.Message)
      Catch ex As Exception
         MessageBox.Show(ex.Message)
      End Try

   End Sub

   Private Sub AddNode(ByRef inXmlNode As XmlNode, ByRef inTreeNode As TreeNode)
      Dim xNode As XmlNode
      Dim tNode As TreeNode
      Dim nodeList As XmlNodeList
      Dim i As Long

      ' Loop through the XML nodes until the leaf is reached.
      ' Add the nodes to the TreeView during the looping process.
      If inXmlNode.HasChildNodes() Then
         nodeList = inXmlNode.ChildNodes
         For i = 0 To nodeList.Count - 1
            xNode = inXmlNode.ChildNodes(i)
            inTreeNode.Nodes.Add(New TreeNode(xNode.Name))
            tNode = inTreeNode.Nodes(i)
            AddNode(xNode, tNode)
         Next
      Else
         ' Here you need to pull the data from the XmlNode based on the
         ' type of node, whether attribute values are required, and so forth.
         inTreeNode.Text = (inXmlNode.OuterXml).Trim
      End If
   End Sub
本文还详细介绍了如何限制显示的数据:

' SECTION 4. Create a new TreeView Node with only the child nodes.
         Dim nodelist As XmlNodeList = dom.SelectNodes("//child")
         Dim cDom As New XmlDocument()
         cDom.LoadXml("<children></children>")
         Dim node As XmlNode
         For Each node In nodelist
            Dim newElem As XmlNode = cDom.CreateNode(XmlNodeType.Element, node.Name, node.LocalName)
            newElem.InnerText = node.InnerText
            cDom.DocumentElement.AppendChild(newElem)
         Next

         TreeView1.Nodes.Add(New TreeNode(cDom.DocumentElement.Name))
         tNode = TreeView1.Nodes(1)
         AddNode(cDom.DocumentElement, tNode)
第4节。创建仅包含子节点的新TreeView节点。 Dim nodelist作为XmlNodeList=dom.SelectNodes(“//子节点”) Dim cDom作为新的XmlDocument() LoadXml(“”) Dim节点作为XmlNode 对于节点列表中的每个节点 Dim newElem As XmlNode=cDom.CreateNode(XmlNodeType.Element、node.Name、node.LocalName) newElem.InnerText=节点.InnerText cDom.DocumentElement.AppendChild(newElem) 下一个 添加(新树节点(cDom.DocumentElement.Name)) tNode=TreeView1.节点(1) AddNode(cDom.DocumentElement,tNode)
这是一个很好的建议,但我希望找到一种在不事先知道对象类型的情况下显示对象的方法。您是否事先知道要显示对象中的哪些固定属性(如名称、说明),或者是否需要根据遇到的对象类型显示不同的属性?如果是前者,您应该能够使用分层数据模板。如果是后者,我不知道如何在xaml中实现这一点,我可能会在遍历对象继承权时(使用反射或其他方法)在代码隐藏中创建树视图项。我希望能够在不知道对象的任何属性的情况下在树视图中显示对象。我将考虑使用反射来实现这一点。除非有其他办法。