【问题标题】:Bind Any XML document to WPF TreeView将任何 XML 文档绑定到 WPF TreeView
【发布时间】:2010-10-24 11:50:31
【问题描述】:

我想使用 TypeConverter 将任何 XML 文档绑定到 WPF TreeView。

我最初的解决方案是使用递归,但是当文档很大时,UI 会被严重占用。

以下链接讨论了 TypeConverter,但针对特定的节点/元素组合: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/edd843b7-b378-4c2d-926f-c053dbd7b340

如果不知道 XML 文档是什么样子怎么办?由于这仅用于显示目的,我现在不太关心功能,我只想将 XML 绑定到 TreeView。

【问题讨论】:

    标签: c# wpf xml treeview typeconverter


    【解决方案1】:

    它适用于其他节点类型,只需进行一些简单的修改。首先,HierarchicalDataTemplate.ItemsSource Binding XPath 必须更改为“child::node()|attribute::*”以允许任何子节点和任何属性。然后,为其他 NodeTypes 添加 DataTriggers。下面的例子对我有用。请注意,我为各种 NodeType 添加了图标,您可能需要删除它们:

            <HierarchicalDataTemplate x:Key="NodeTemplate">
            <StackPanel Orientation="Horizontal">
            <Image x:Name="icon" VerticalAlignment="Center" Margin="1,1,4,1"/>
            <TextBlock x:Name="name" Text="" />
            <TextBlock x:Name="inter" Text="" />
            <TextBlock x:Name="value" Text="" />
            </StackPanel>
            <HierarchicalDataTemplate.ItemsSource>
                <Binding XPath="child::node()|attribute::*" />
            </HierarchicalDataTemplate.ItemsSource>
            <HierarchicalDataTemplate.Triggers>
                <DataTrigger Binding="{Binding Path=NodeType}" Value="Element">
                    <Setter TargetName="icon" Property="Source" Value="icons/element.png"></Setter>
                    <Setter TargetName="name" Property="Text" Value="{Binding Path=Name}"></Setter>
                </DataTrigger>
                <DataTrigger Binding="{Binding Path=NodeType}" Value="Text">
                    <Setter TargetName="icon" Property="Source" Value="icons/text.png"></Setter>
                    <Setter TargetName="value" Property="Text" Value="{Binding Path=Value}"></Setter>
                </DataTrigger>
                <DataTrigger Binding="{Binding Path=NodeType}" Value="Attribute">
                    <Setter TargetName="icon" Property="Source" Value="icons/attribute.png"></Setter>
                    <Setter TargetName="name" Property="Text" Value="{Binding Path=Name}"></Setter>
                    <Setter TargetName="inter" Property="Text" Value=": "></Setter>
                    <Setter TargetName="value" Property="Text" Value="{Binding Path=Value}"></Setter>
                </DataTrigger>
                <DataTrigger Binding="{Binding Path=NodeType}" Value="CDATA">
                    <Setter TargetName="icon" Property="Source" Value="icons/cdata.png"></Setter>
                    <Setter TargetName="value" Property="Text" Value="{Binding Path=Value}"></Setter>
                </DataTrigger>
                <DataTrigger Binding="{Binding Path=NodeType}" Value="Comment">
                    <Setter TargetName="icon" Property="Source" Value="icons/comment.png"></Setter>
                    <Setter TargetName="value" Property="Text" Value="{Binding Path=Value}"></Setter>
                </DataTrigger>
                <DataTrigger Binding="{Binding Path=NodeType}" Value="ProcessingInstruction">
                    <Setter TargetName="icon" Property="Source" Value="icons/pi.png"></Setter>
                    <Setter TargetName="value" Property="Text" Value="{Binding Path=Value}"></Setter>
                </DataTrigger>
            </HierarchicalDataTemplate.Triggers>
        </HierarchicalDataTemplate>
    

    【讨论】:

      【解决方案2】:

      所以我问了一个问题,关于如何通过以下方式将任何 XML 文档绑定到树视图而不考虑架构: 1. 通过 XML Provider 和 HierarchicalDataTemplate 将 XML Document 绑定到 WPF TreeView。 2. 显示 XML 文档的所有节点,包括具有子节点的节点,格式如下:

      >节点1

      Node1 内容

          >ChildNode1
      
             ChildNode1 Contents
      
                  >ChildNode1'sChildNode
      
                    ChildNode1'sChildNode Contents
      

      >节点2

        Node2 Contents
      

      问题是我的 TreeView 将每个 XmlNode 名称属性绑定到 TreeItem。如果是文本 XmlNode,它会将#text 绑定到不是我想要的 TreeItem。

      所以通过 MSDN 论坛上的帖子,我得到了答案: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/cbdb2420-1403-436f-aa7f-b1e3b1acb398/

      所以诀窍是使用触发器根据遇到的节点类型设置值。

      需要注意的是,其他类型的节点将被忽略,并且 XML 文档可能包含不同的元素,因此这可能不适用于遇到的每种类型的节点。

      这是 XAML:

      <Window x:Class="WpfApplication1.Window1" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:local="clr-namespace:WpfApplication1"
          Title="Window1" Height="250" Width="450">
      
      <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>
      

      public Window1()
      {
      InitializeComponent();
      XmlDataProvider dataProvider = this.FindResource("xmlDataProvider") as XmlDataProvider;
              XmlDocument 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;
          }
      

      【讨论】:

        【解决方案3】:

        看看我在以下线程上的回答 - Binding XML data to WPF treeview Control 我相信这正是您正在寻找的。线程中的链接指向一个帖子,它为您提供了一个分步示例,并提供了一个选项下载源代码。该示例以将任何 XML文档绑定到WPF树视图的方式编写

        【讨论】:

          猜你喜欢
          • 2017-01-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-07-09
          • 1970-01-01
          • 2010-09-19
          • 2011-07-06
          • 1970-01-01
          相关资源
          最近更新 更多