2013-09-25 35 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

很酷,很好的建议,我敢肯定。任何关于向树添加属性的想法,还是需要不同的方法? –