将 xml 文档动态绑定到树视图
本文关键字:视图 动态绑定 xml 文档 | 更新日期: 2023-09-27 18:32:41
在这个详细介绍如何将树视图呈现和绑定到 xml 文档的出色答案的基础上,我想知道是否有人可以提供一种方法来使其更通用,以便它可以接受任何有效的 xml。
<HierarchicalDataTemplate x:Key="colorsTemplate">
<TextBox Text="{Binding XPath=@Name, Mode=TwoWay}" />
</HierarchicalDataTemplate>
<HierarchicalDataTemplate x:Key="rootTemplate" ItemsSource="{Binding XPath=FavoriteColors/Color}" ItemTemplate="{StaticResource colorsTemplate}">
<StackPanel Orientation="Horizontal">
<TextBox Text="{Binding XPath=@FirstName, Mode=TwoWay}" />
<TextBlock Text=" " />
<TextBox Text="{Binding XPath=@LastName, Mode=TwoWay}" />
<TextBlock Text=" (Age: " />
<TextBox Text="{Binding XPath=@Age, 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 中了解属性名称?
您将如何声明分层数据模板,因为节点的深度在运行时之前是未知的?
我的假设是模板必须构建在隐藏的代码中,但也许这是不正确的。
谁能举出一个例子来说明如何做到这一点?
诀窍是将 XPath-Expression 更改为 child::node() 并实现一个数据触发器来区分节点和属性。
哈姆勒
<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;
}
}