2011-07-20 77 views
1

我有我反序列化爲對象的XML文件,現在我想在一個WPF TreeView控件來顯示該對象。我一直在尋找與WPF TreeView數據綁定,但我一直沒能找到我在找什麼。數據綁定到WPF TreeView的通用對象?

有沒有辦法有WPF樹視圖顯示對象和它的孩子們事先不知道對象的結構是什麼樣子?

回答

1

假設你的對象看起來像:

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

爲每個非葉實體和每一片葉子實體數據模板的分層數據模板。

我發現它很容易適應任何類型的混合層次的,如果你在你的對象必須在包含任何類型下方的孩子每個級別一個ObservableCollection(稱爲類似的項目)。

採用這種設置,模板看起來是這樣的:

 <!-- 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}" /> 

這個答案假設你知道的類型,您正在處理的對象,但想要處理這些對象的任何結構/層次結構,並且如果不知道某個特定對象類型是否將成爲葉子對象類型,則始終可以使用分層數據模板。

+0

一個很好的建議,但我希望能找到一條出路不知道對象的類型事先顯示對象。 – user817722

+0

您是否事先知道要顯示的對象中的固定屬性(例如名稱,說明),還是需要根據遇到的對象的類型顯示不同的屬性?如果它是前者,則應該能夠使用分層數據模板。如果是後者,我不知道如何在xaml中做到這一點,我可能會在後面的代碼中創建樹視圖項目,同時穿過對象層(使用反射或其他方式)。 –

+0

我希望能夠在不知道對象的任何屬性的情況下在TreeView中顯示對象。我會着眼於使用反射來做到這一點。除非有其他方法。 – user817722

1

你必須爲所有可能的類型提供分層數據模板。

0

我不知道,你會發現一個乾淨的數據綁定解決方案,允許對象的無知,但考慮到您最初從XML反序列化,你也許可以序列化回XML。鑑於這樣的話,你就可以在TreeView控件中顯示的XML序列化數據:

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

從文章:

在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)