2013-09-25 33 views
1

基於this excellent answer構建,詳細說明如何將樹視圖呈現和綁定到xml文檔,我想知道是否有人可以提供使其更通用的方法,以便它可以接受任何有效的xml。將xml文檔動態綁定到樹視圖

 <HierarchicalDataTemplate x:Key="colorsTemplate"> 
      <TextBox Text="{Binding [email protected], Mode=TwoWay}" /> 
     </HierarchicalDataTemplate> 

     <HierarchicalDataTemplate x:Key="rootTemplate" ItemsSource="{Binding XPath=FavoriteColors/Color}" ItemTemplate="{StaticResource colorsTemplate}"> 
      <StackPanel Orientation="Horizontal"> 
       <TextBox Text="{Binding [email protected], Mode=TwoWay}" /> 
       <TextBlock Text=" " /> 
       <TextBox Text="{Binding [email protected], Mode=TwoWay}" /> 
       <TextBlock Text=" (Age: " /> 
       <TextBox Text="{Binding [email protected], Mode=TwoWay}" /> 
       <TextBlock Text=")" /> 
      </StackPanel> 
     </HierarchicalDataTemplate> 

例如,假設負載按鈕,而不是靜態加載People.xml,提出了一個文件對話框,用戶可以上傳任何XML文件。
所以這

private void Load_Click(object sender, RoutedEventArgs e) 
{ 
    var xmlDocument = new XmlDocument(); 
    xmlDocument.Load("People.xml"); 
    people.Document = xmlDocument; 
} 

一下會更喜歡這樣

private void Load_Click(object sender, RoutedEventArgs e) 
{ 
    var xmlDocument = new XmlDocument(); 
    Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog(); 
    bool? result = dlg.ShowDialog(); 

    if (result == true) { 
     xmlDocument.Load(dlg.FileName); 
     people.Document = xmlDocument; 
    } 
} 

怎能定義綁定,這似乎依賴於從XML屬性名稱的知識被處理?

而你將如何聲明HierarchicalDataTemplates,因爲在運行之前節點的深度是未知的?

我的假設是,模板將不得不建立在後面的代碼中,但也許這是不正確的。

任何人都可以啓動一個如何實現這個目標的例子嗎?

回答

2

訣竅是將XPath-Expression更改爲child :: node()並實現數據觸發器以區分節點和屬性。

的XAML

<Window x:Class="XmlDataBinding.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 

    <Window.Resources> 
     <HierarchicalDataTemplate x:Key="NodeTemplate"> 
      <TextBlock x:Name="text" 
         Text="?" /> 
      <HierarchicalDataTemplate.ItemsSource> 
       <Binding XPath="child::node()" /> 
      </HierarchicalDataTemplate.ItemsSource> 
      <HierarchicalDataTemplate.Triggers> 
       <DataTrigger Binding="{Binding Path=NodeType}" 
          Value="Text"> 
        <Setter TargetName="text" 
          Property="Text" 
          Value="{Binding Path=Value}"></Setter> 
       </DataTrigger> 
       <DataTrigger Binding="{Binding Path=NodeType}" 
          Value="Element"> 
        <Setter TargetName="text" 
          Property="Text" 
          Value="{Binding Path=Name}"></Setter> 
       </DataTrigger> 
      </HierarchicalDataTemplate.Triggers> 

     </HierarchicalDataTemplate> 

     <XmlDataProvider x:Key="xmlDataProvider"></XmlDataProvider> 

    </Window.Resources> 


    <Grid> 
     <TreeView Name="treeView1" 
        Background="AliceBlue" 
        ItemsSource="{Binding Source={StaticResource xmlDataProvider}, XPath=*}" 
        ItemTemplate="{StaticResource NodeTemplate}" /> 

    </Grid> 
</Window> 

代碼隱藏(替代視圖模型適量)

public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 

      var dataProvider = this.FindResource("xmlDataProvider") as XmlDataProvider; 
      var doc = new XmlDocument(); 
      // Testdocument 
      doc.LoadXml(
       @"<root> 
        <child1>text1<child11>text11</child11> 
        </child1> 
        <child2>text2<child21>text21</child21> 
         <child22>text22</child22> 
        </child2> 
        </root>"); 
      dataProvider.Document = doc; 
     } 
    } 
+0

很不錯的。我有兩個後續問題:你將如何使文本可編輯(簡單地添加一個TextBox控件似乎比它應該更復雜)。而且,你怎麼能處理屬性呢?那就是如果它寫成'' –

+0

編輯是一個全新的球賽。我的方法是解析xml文檔並創建一系列NodeViewModel,每個NodeViewModel具有AttributeViewModel和NodeVieWModel(Child nodeS)集合。您的每個視圖模型都將使用XmlNode作爲其內部模型,並且ViewModel可以調解將值寫入底層Xml文檔。儘管如此,這確實值得一個全新的問題。 –

+0

很酷,很好的建議,我敢肯定。任何關於向樹添加屬性的想法,還是需要不同的方法? –