Действительно ли рекурсивные DataTemplates возможны?

У меня есть класс что-то как:

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
    }
}

То, которое содержится в другом классе, позволяет, называют его OtherClass ради аргумента, который переносит его и используется в WPF в ObjectDataProvider.

Как Вы видите, экземпляр Section может содержать много других экземпляров Section.

Существует ли путь в XAML для создания шаблона, который имеет дело с этой рекурсией?

Это - то, что я имею до сих пор:

<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>

Но я не могу получить рекурсию, как a DataTemplate может только сослаться на тот, который объявляется перед ним.

Это может быть сделано в XAML? Если так, как? Это - что-то, что я должен буду сделать в коде позади?

DataTemplates являются даже способом пойти? Существует ли лучший способ отобразить и отредактировать эти данные?

16
задан Matt Ellen 21 July 2010 в 14:00
поделиться

2 ответа

Возможно, я неправильно понимаю ваш сценарий, но является ли HierarchicalDataTemplate тем, что вы ищете?

2
ответ дан 30 November 2019 в 17:51
поделиться

На случай, если кому-то понадобится увидеть, как это сделать, не используя 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>

Это дает мне в основном то, что я хочу.

Основное изменение, как предложил Дэн Брайант: изменение ItemTemplate для использования динамического, а не статического ресурса для рекурсивного объекта ( раздел ).

28
ответ дан 30 November 2019 в 17:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: