数据将通用对象绑定到WPF TreeView?

时间:2011-07-20 18:07:18

标签: c# wpf treeview

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

有没有办法让WPF TreeView显示一个对象,而它的子节点却不知道对象结构是什么样的?

3 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

假设您的对象看起来像:

    Entity A
        Entity B
            Entity C
            Entity C
        Entity B
    Entity D

为每个非叶子实体创建一个分层数据模板,为每个叶子实体创建一个数据模板。

我发现,如果你的对象中有一个ObservableCollection(在类似于Items之类的东西),它包含任何类型的混合层次结构,那么它包含下面任何类型的子节点。

通过此设置,模板看起来像:

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

树视图绑定:

    <TreeView ItemsSource="{Binding Items, Mode=OneWay}" />

这个答案假设你知道你正在处理的对象的类型,但是想要处理这些对象的任何结构/层次结构,如果你不知道特定的对象类型是否会成为叶子,您始终可以使用分层数据模板。

答案 2 :(得分:0)

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

http://support.microsoft.com/kb/308063

来自文章:

在Form1.vb文件中,在&#34; Windows窗体设计器生成的代码&#34;之后替换整个代码。包含以下示例代码的部分:

 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)