如何将Xml属性绑定到Treeview节点,同时将XDocument绑定到WPF Treeview
我有一个XML需要将数据绑定到WPF TreeView。这里的XML可以有不同的结构。 TreeView应该是数据绑定通用的,足以加载任何层次结构的排列。然而,一个XAttribute节点上(称为标题)应数据绑定到TreeViewItem的标题文本和不是节点名。要绑定如何将Xml属性绑定到Treeview节点,同时将XDocument绑定到WPF Treeview
XML:
<Wizard>
<Section Title="Home">
<Loop Title="Income Loop">
<Page Title="Employer Income"/>
<Page Title="Parttime Job Income"/>
<Page Title="Self employment Income"/>
</Loop>
</Section>
<Section Title="Deductions">
<Loop Title="Deductions Loop">
<Page Title="Travel spending"/>
<Page Title="Charity spending"/>
<Page Title="Dependents"/>
</Loop>
</Section>
</Wizard>
XAML:
<Window x:Class="Wpf.DataBinding.TreeViewer"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Wpf.DataBinding"
Title="TreeViewer" Height="300" Width="300">
<Window.Resources>
<HierarchicalDataTemplate ItemsSource="{Binding Path=Elements}" x:Key="TVTemplate">
<TreeViewItem Header="{Binding Path=Name}"/>
</HierarchicalDataTemplate>
</Window.Resources>
<StackPanel>
<TreeView x:Name="_treeView" Style="{StaticResource TVallExpanded}"
ItemsSource="{Binding Path=Root.Elements}"
ItemTemplate="{StaticResource TVTemplate}" />
</StackPanel>
</Window>
加载XML到的XDocument并结合其XAML的代码隐藏到TreeView的
public partial class TreeViewer : Window
{
public TreeViewer()
{
InitializeComponent();
XDocument doc = XDocument.Parse(File.ReadAllText(@"C:\MyWizard.xml"));
_treeView.DataContext = doc;
}
}
所以在XAML标记我们将Name绑定到TreeViewItem的头部。
<TreeViewItem Header="{Binding Path=Name}"/>
但是,我想将其绑定到标题科,循环和页面的属性在上面的XML。我读过,绑定XDocument时不能使用XPath。但是必须有一种方法将标题属性绑定到TreeViewItem的标题文本。我尝试过使用@Title,[@ Title]等,但似乎没有任何工作。
这个thread on MSDN Forums有类似的讨论。
任何指针都会非常有帮助。
万岁!我想出了如何绑定XAttribute。这不直观,也不容易想象。但这是如何做到的。
<TreeViewItem Header="{Binding Path=Attribute[Title].Value}"/>
很难想象Title可以直接用在方括号中。
我认为,所有你需要做的是在你的XML创建为每个节点类型HierarchicalDataTemplate,你的XML其加载到XmlDataProvider,然后绑定是到TreeView。电视与XDP协同工作来绑定数据,并沿着线路的某处找出您已定义的HDT并将其DataType与XML中节点的名称相匹配。 XPATH可能会随着数据类型的不同而发生变化,但保持灵活性是另一个问题。
例如,我有一个小正则表达式测试应用程序。它包括一个帮助系统,它基本上是树中列出的所有不同的正则表达式部分:类别和部分与描述,工具提示和其他东西。有关零件的数据存储为一个xml数据源。由于它的静态,我刚刚创建与应用程序的资源静态资源:
<XmlDataProvider
x:Key="rxPartData"
XPath="RegexParts">
<x:XData>
<RegexParts
xmlns="">
<Category
Name="Character class"
ToolTip="Sets of characters used in matching">
<RegexPart
Regex="[%]"
Hint="Positive character group"
ToolTip="Matches any character in the specified group (replace % with one or more characters)" />
<!-- yadda -->
</Category>
</RegexParts>
</x:XData>
</XmlDataProvider>
接下来,我创建HierarchicalDataTemplates在数据(同样,这一切是在应用程序的资源),每个节点类型:
<!-- Category data template -->
<HierarchicalDataTemplate
DataType="Category"
ItemsSource="{Binding XPath=*}">
<TextBlock
Focusable="False"
Text="{Binding [email protected]}"
ToolTip="{StaticResource CategoryTooltip}"
ToolTipService.InitialShowDelay="0"
ToolTipService.ShowDuration="{x:Static sys:Int32.MaxValue}"
ToolTipService.HasDropShadow="True" />
</HierarchicalDataTemplate>
<!-- RegexPart data template -->
<HierarchicalDataTemplate
DataType="RegexPart"
ItemsSource="{Binding XPath=*}">
<WrapPanel
Focusable="False"
ToolTip="{StaticResource RegexPartTooltip}"
ToolTipService.InitialShowDelay="0"
ToolTipService.ShowDuration="{x:Static sys:Int32.MaxValue}"
ToolTipService.HasDropShadow="True">
<TextBlock
Text="{Binding [email protected]}" />
<TextBlock
Text=" - " />
<TextBlock
Text="{Binding [email protected]}" />
</WrapPanel>
</HierarchicalDataTemplate>
最后,我只是约束树到XmlDataProvider:
<TreeView
Name="_regexParts"
DockPanel.Dock="Top"
SelectedItemChanged="RegexParts_SelectedItemChanged"
ItemsSource="{Binding Source={StaticResource rxPartData}, XPath=/RegexParts/Category}"
ToolTip="Click the + to expand a category; click a part to insert it">
</TreeView>
而这一切,你必须做的。 TreeView和XmlDataProvider将负责为数据中的正确节点查找并使用正确的HDT's。所有这些中最难的部分是找出你的xpaths进行绑定。它可能会有点棘手,就像你的路径不正确,你最终会在树中没有任何东西,并且不会有任何错误(在WPF数据绑定中有增加错误报告的方法,但这是另一个问题) 。
Thanks Will。你已经添加了一些非常好的信息。但我不喜欢XmlDataProvider的情况下,我正在与。虽然我的示例从文件加载XML,但实际上我直接将XDocument绑定到电视。尽管我找到了解决方案。将它作为答案发布。 – Vin 2008-10-26 17:04:08
正如你在我的例子中看到的那样,使用XmlDataProvider可以让你将树的所有模板分解为HDT,从而大大简化你的xaml。您可以将XDocument合并到您的代码隐藏中,没有问题。但是,如果这对你有用,那么你就有更多的权力。 – Will 2008-10-26 18:30:53