我有这个简单的XML:
<ChangeLog>
<Release Version="1.0.1">
<Change Name="Feature2" Description="Something changed"/>
<Change Name="Feature1" Description="Bug fixed"/>
</Release>
<Release Version="1.0.0">
<Change Name="Feature2" Description="Something new added"/>
<Change Name="Feature1" Description="Something new added"/>
</Release>
</ChangeLog>
我希望将其显示在TreeView
中,如下所示:
我已经查看了here,here以及其他一些相关链接,但我找到的示例使用单HierarchicalDataTemplate
来显示项目,而我需要HierarchicalDataTemplate
适用于Release
元素,DataTemplate
适用于Change
元素。
例如,对于视图模型,资源中会出现类似的情况(模板树被省略):
<HierarchicalDataTemplate DataType="{x:Type local:Release}" ItemsSource="{Binding Changes}" />
<DataTemplate DataType="{x:Type local:Change}" ItemsSource="{Binding Changes}" />
是否有可能不将XML包装到视图模型中?
答案 0 :(得分:0)
我已经想通了,怎么做。
解决方案的根目录是DataTemplateSelector
,以便为不同的XML元素提供适当的数据模板:
public sealed class ElementsTemplateSelector : DataTemplateSelector
{
public DataTemplate ReleaseTemplate { get; set; }
public DataTemplate ChangeTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
var element = item as XElement;
if (element != null)
{
switch (element.Name.ToString())
{
case "Release":
return ReleaseTemplate;
case "Change":
return ChangeTemplate;
}
}
return base.SelectTemplate(item, container);
}
}
然后XAML将如下所示:
<Grid>
<Grid.Resources>
<local:ElementsTemplateSelector x:Key="ElementsTemplateSelectorKey">
<local:ElementsTemplateSelector.ReleaseTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Elements}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Release:"/>
<TextBlock Margin="2,0,0,0" Text="{Binding Attribute[Version].Value}"/>
</StackPanel>
</HierarchicalDataTemplate>
</local:ElementsTemplateSelector.ReleaseTemplate>
<local:ElementsTemplateSelector.ChangeTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Attribute[Name].Value}"/>
<TextBlock Text=":"/>
<TextBlock Margin="2,0,0,0" Text="{Binding Attribute[Description].Value}"/>
</StackPanel>
</DataTemplate>
</local:ElementsTemplateSelector.ChangeTemplate>
</local:ElementsTemplateSelector>
</Grid.Resources>
<TreeView ItemsSource="{Binding Path=Root.Elements}" ItemTemplateSelector="{StaticResource ElementsTemplateSelectorKey}"/>
</Grid>
P.S。此代码假定当前数据上下文为XDocument
实例:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = XDocument.Load("file://D:/ChangeLog.xml");
}
}