如何在XAML中显示递归属性

时间:2016-04-22 08:16:07

标签: c# wpf xaml

我有一个类,看起来像

public class MyClass 
{
    public string MyTitle{get;set;}
    public MyClass Child{get;set;
}

原因是孩子和父母之间只有1对1的关系(意思是,没有父母会有多个孩子)。

我想在WPF应用程序中进行此处,其中每个MyTitle将水平显示(基于总共有多少父和子)。 EG,类似

MyClass.MyTitle       MyClass.Child.MyTitle       MyClass.Child.Child.MyTitle  etc

在网络世界中,我们可以添加循环和if语句,只需检查子项是否为null(或不是),然后附加下一项。

在网络世界中,像(伪代码)

item = Model.MyClass;

do while(true) {    
    if (item != null) {
        <div class="floatLeft">item.MyTitle</div>
    }
    else {
        break;
    }
    item = parent.Child;
}

XAML似乎限制我使用模板。虽然我确定我会使用C#解决方案直接绑定,但我还是以此为契机,了解有关XAML的更多信息。

问题是,它不是一个列表,所以我不确定使用ItemsControl / ListView / etc是否是正确的方法。我甚至不确定我能做什么。

所以我的问题是,这只能使用XAML吗?

2 个答案:

答案 0 :(得分:3)

如下所示的简单DataTemplate可以完成这项工作。通过设置其DataType属性,当内容类型与DataType匹配时,它将自动应用于ContentPresenters,ContentControls等Content,这也将以递归方式工作。

<Window.Resources>
    <DataTemplate DataType="{x:Type local:MyClass}">
        <StackPanel Orientation="Horizontal">
            <TextBlock Margin="4" Text="{Binding MyTitle}"/>
            <ContentPresenter Content="{Binding Child}"/>
        </StackPanel>
    </DataTemplate>
</Window.Resources>

鉴于窗口的DataContext包含MyClass实例,您只需编写

即可
<ContentControl Content="{Binding}"/>

并且DataTemplate将自动递归应用。

您可以尝试设置DataContext,如

DataContext = new MyClass
{
    MyTitle = "Item1",
    Child = new MyClass
    {
        MyTitle = "Item2",
        Child = new MyClass
        {
            MyTitle = "Item3",
        }
    }
};

答案 1 :(得分:2)

如果MyClass始终具有固定数量的子MyClass元素,则可以制作递归模板

<Window x:Class="WpfApplication2.TestWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:wpfApplication2="clr-namespace:WpfApplication2"
        Title="TestWindow" Height="300" Width="300">
    <Window.Resources>
    <DataTemplate DataType="{x:Type wpfApplication2:MyClass}">
        <WrapPanel Orientation="Horizontal">
            <TextBlock Text=" => " FontSize="18" Margin="5,0"/>
            <TextBlock Text="{Binding MyTitle}" FontSize="18"/>
            <ContentControl Content="{Binding Child}"/>
        </WrapPanel>
    </DataTemplate>    

    </Window.Resources>

    <Grid>
      <Border BorderBrush="Blue" BorderThickness="1" 
            Margin="5" VerticalAlignment="Top">
        <ContentControl Content="{Binding .}"/>
      </Border>
    </Grid>
</Window>
public partial class TestWindow : Window
{
    public TestWindow()
    {
        InitializeComponent();
        // test DataContext
        DataContext = new MyClass
        {
            MyTitle = "1234567890",
            Child = new MyClass
            {
                MyTitle = "qwerty uiop ",
                Child = new MyClass
                {
                    MyTitle = "asdf ghjkl"
                }
            }
        };
    }
}

enter image description here