在this excellent answer上构建详细说明如何将树视图呈现并绑定到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中属性名称的知识?
您如何声明HierarchicalDataTemplates,因为在运行之前节点的深度是未知的?
我的假设是模板必须在后面的代码中构建,但也许这是不正确的。
有人可以提出一个如何实现这一目标的例子吗?
答案 0 :(得分: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>
代码隐藏(替代ViewModel品尝)
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;
}
}