Are recursive DataTemplates possible?

不问归期 提交于 2019-12-19 05:09:09

问题


I have a class something like:

public class Section
{
    private IEnumerable<Section> sections;
    private IEnumerable<KeyValuePair<string, string>> attributes

    public string Name {get;set;}
    public IEnumerable<Section> Sections
    {
        get {return sections;}
    }
    public IEnumerable<KeyValuePair<string, string>> Attributes
    {
        get {return attributes;}
    }

    public Section(...)
    {
        //constructor logic
    }
}

Which is contained in another class, lets call it OtherClass for sake of argument, that wraps around it and is used in WPF in an ObjectDataProvider.

As you can see, an instance of Section can contain many other instances of Section.

Is there a way in XAML to create a template that deals with this recursion?

This is what I've got so far:

<UserControl x:Class="OtherClassEditor"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:OtherClassNS="clr-namespace:NameSpace"
    Height="300" Width="300">
    <UserControl.Resources>
        <ObjectDataProvider ObjectType="{x:Type OtherClassNS:OtherClass}" x:Key="ViewModel" />
        <DataTemplate x:Key="listViewAttr">
            <WrapPanel>
                <TextBlock Text="{Binding Path=Key}"></TextBlock><TextBlock Margin="0,0,4,0">: </TextBlock>
                <TextBlock Text="{Binding Path=Value}"></TextBlock>
            </WrapPanel>
        </DataTemplate>
        <DataTemplate x:Key="listViewSection">
            <StackPanel>
                <WrapPanel Margin="0,0,0,8">
                    <TextBlock Margin="0,0,4,0">Section:</TextBlock>
                    <TextBlock Text="{Binding Path=Name}"/>
                </WrapPanel>
            </StackPanel>
        </DataTemplate>
        <DataTemplate x:Key="listViewData">
            <StackPanel>
                <WrapPanel Margin="0,0,0,8">
                    <TextBlock Margin="0,0,4,0">Section: </TextBlock>
                    <TextBlock Text="{Binding Path=Name}"/>
                    <ListView DataContext="{Binding Path=Sections}" ItemTemplate="{StaticResource listViewSection}" ItemsSource="{Binding Sections}">
                    </ListView>
                    <ListView DataContext="{Binding Path=Attributes}" ItemsSource="{Binding Attributes}" ItemTemplate="{StaticResource listViewAttr}">

                    </ListView>
                </WrapPanel>
            </StackPanel>    
        </DataTemplate>
    </UserControl.Resources>
    <Grid>
        <ListView DataContext="{StaticResource ViewModel}" ItemTemplate="{StaticResource listViewData}" ItemsSource="{Binding Sections}">
        </ListView>
    </Grid>
</UserControl>

But I can't get recursion, as a DataTemplate can only reference one that is declared before it.

Can this be done in XAML? If so, how? Is this something that I'll have to do in code behind?

Are DataTemplates even the way to go? Is there a better way to display and edit this data?


回答1:


Perhaps I'm misunderstanding your scenario, but is HierarchicalDataTemplate what you're looking for?




回答2:


In case anyone needs to see how to do this without using an HierarchicalDataTemplate:

<UserControl x:Class="OtherClassEditor"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:OtherClassNS="clr-namespace:NameSpace"
    Height="300" Width="300">
    <UserControl.Resources>
        <ObjectDataProvider ObjectType="{x:Type OtherClassNS:OtherClass}" x:Key="ViewModel" />
        <DataTemplate x:Key="listViewAttr">
            <WrapPanel>
                <TextBlock Text="{Binding Path=Key}"></TextBlock>
                <TextBlock Margin="0,0,4,0">: </TextBlock>
                <TextBlock Text="{Binding Path=Value}"></TextBlock>
            </WrapPanel>
        </DataTemplate>
        <DataTemplate x:Key="listViewData">
            <StackPanel>
                <WrapPanel Margin="0,0,0,8">
                    <TextBlock Margin="0,0,4,0">Section: </TextBlock>
                    <TextBlock Text="{Binding Path=Name}"/>
                </WrapPanel>
                <ListView ItemTemplate="{DynamicResource listViewData}" ItemsSource="{Binding Sections}" />
                <ListView ItemsSource="{Binding Attributes}" ItemTemplate="{StaticResource listViewAttr}" />
            </StackPanel>    
        </DataTemplate>
    </UserControl.Resources>
    <Grid>
        <ListView DataContext="{StaticResource ViewModel}" ItemTemplate="{DynamicResource listViewData}" ItemsSource="{Binding Sections}">
        </ListView>
    </Grid>
</UserControl>

This gets me basically what I want.

The main change is as Dan Bryant suggested: changing the ItemTemplate to use a Dynamic rather than static resource for the recursive object (Section).



来源:https://stackoverflow.com/questions/3299915/are-recursive-datatemplates-possible

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!