C# 将任何 XML 文档绑定到 WPF TreeView
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/834632/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Bind Any XML document to WPF TreeView
提问by Boris Kleynbok
I would like to bind any XML document to WPF TreeView using TypeConverter.
我想使用 TypeConverter 将任何 XML 文档绑定到 WPF TreeView。
My original solution was to use recursion, but when document is large UI is heavily tied up.
我最初的解决方案是使用递归,但是当文档很大时,UI 被严重束缚。
Following link talks about TypeConverter but for particular node/element combination: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/edd843b7-b378-4c2d-926f-c053dbd7b340
以下链接讨论 TypeConverter 但对于特定节点/元素组合:http: //social.msdn.microsoft.com/Forums/en-US/wpf/thread/edd843b7-b378-4c2d-926f-c053dbd7b340
What if not known what XML document looks like? Since this is for display purposes only I don't care much about functionality at this point I just want to bind XML to a TreeView.
如果不知道 XML 文档是什么样的怎么办?由于这仅用于显示目的,因此我现在不太关心功能,我只想将 XML 绑定到 TreeView。
回答by Boris Kleynbok
So I have asked a question on how to bind any XML document regardless of schema to tree view in the following way: 1. Bind XML Document to WPF TreeView via XML Provider and HierarchicalDataTemplate. 2. Display all nodes of the XML Document including those that have child nodes in following format:
所以我问了一个问题,关于如何通过以下方式将任何 XML 文档绑定到树视图,而不管架构如何: 1. 通过 XML Provider 和 HierarchicalDataTemplate 将 XML 文档绑定到 WPF TreeView。2. 显示 XML 文档的所有节点,包括具有以下格式的子节点的节点:
>Node1
>节点1
Node1 Contents
节点 1 内容
>ChildNode1
ChildNode1 Contents
>ChildNode1'sChildNode
ChildNode1'sChildNode Contents
>Node2
>节点2
Node2 Contents
Problem was that my TreeView was binding each XmlNode name property to TreeItem. In case of text XmlNode it would bind #text to the TreeItem which was not what I wanted.
问题是我的 TreeView 将每个 XmlNode 名称属性绑定到 TreeItem。在文本 XmlNode 的情况下,它会将 #text 绑定到 TreeItem 这不是我想要的。
So via a post on MSDN forum I got my answer: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/cbdb2420-1403-436f-aa7f-b1e3b1acb398/
因此,通过 MSDN 论坛上的帖子,我得到了答案:http: //social.msdn.microsoft.com/Forums/en-US/wpf/thread/cbdb2420-1403-436f-aa7f-b1e3b1acb398/
So the trick was to use triggers to set value based on type of node encountered.
所以诀窍是使用触发器根据遇到的节点类型设置值。
Caveat is that other types of nodes will be ignored and XML document may contain diffrent elements, so this might not work for every type of node encountered.
需要注意的是,其他类型的节点将被忽略,并且 XML 文档可能包含不同的元素,因此这可能不适用于遇到的每种类型的节点。
Here's XAML:
这是 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;
}
回答by receptor
It works for other node types with a few simple modifications. First, HierarchicalDataTemplate.ItemsSource Binding XPath must be changed to "child::node()|attribute::*" to allow any child node and any attribute. Then, add DataTriggers for other NodeTypes. The example below worked for me. NOTE that i added icons for various NodeTypes, you might want to remove them:
它适用于其他节点类型,只需进行一些简单的修改。首先,必须将 HierarchicalDataTemplate.ItemsSource Binding XPath 更改为“child::node()|attribute::*”以允许任何子节点和任何属性。然后,为其他 NodeType 添加 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>
回答by Denys Wessels
Have a look at my answer on the following thread - Binding XML data to WPF treeview Controli believe this is exactly what you're looking for.The link in the thread points to a post which gives you a step by step example with an option to download the source code.The example is written in such a way as to bind anyXML document to a WPF tree view
看看我对以下线程的回答 - 将XML 数据绑定到 WPF 树视图控件我相信这正是您要寻找的。线程中的链接指向一个帖子,该帖子为您提供了一个带有选项的分步示例下载源代码。该示例的编写方式是将任何XML 文档绑定到 WPF 树视图