wpf - 递归数据模板可能吗?

标签 wpf xaml datatemplate

我有一个类是这样的:

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>

但我无法递归,作为 DataTemplate只能引用在它之前声明的一个。

这可以在 XAML 中完成吗?如果是这样,怎么做?这是我必须在代码后面做的事情吗?

数据模板甚至是要走的路吗?有没有更好的方法来显示和编辑这些数据?

最佳答案

如果有人需要查看如何在不使用 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>

这基本上得到了我想要的。

正如 Dan Bryant 所建议的那样,主要变化是:更改 ItemTemplate为递归对象( Section )使用动态而不是静态资源。

关于wpf - 递归数据模板可能吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3299915/

相关文章:

c# - 如何在 XAML 中格式化 TimeSpan

c# - UWP CommandBar 底部有空隙

mvvm - 自己的 DataTemplateSelector MVVM

c# - 项目具有多个可选区域的列表框

c# - 更改 DataTemplate 中存在的 TextBlock 文本

wpf - 在 WPF 应用程序中启动 Toastnotification

c# - WPF DataGrid 自动生成列顺序

c# - 无法解析 System.Drawing.Bitmap 和 System.Drawing.ImageConverter

c# - WPF:截图并保存

c# - WPF:将文本框输入格式化为用户类型