绑定到集合时的条件DataTemplates

时间:2011-12-01 15:41:34

标签: wpf wpf-controls

示例应用程序:

提供的代码所属的示例应用程序通过Binding显示Vehicle个对象的列表。 Vehicle类是一个顶级类,子类可以从例如CarBike。此示例应用程序显示Vehicle的所有者名称。

样本型号代码:

public class Vehicle
{
    private string _ownerName;
    public string ownerName
    {
        get { return _ownerName; }
        set { _ownerName = value; }
    }
}

public class Car : Vehicle
{
    public int doors;
}

public class Bike : Vehicle
{
    // <insert variables unique to a bike, ( I could not think of any...)>
}

UserControl XAML代码:

<Grid>
    <Grid.Resources>
        <DataTemplate x:Key="itemTemplate">
            <WrapPanel>
                <TextBlock Text="{Binding Path=ownerName}"/>
            </WrapPanel>
        </DataTemplate>
    </Grid.Resources>
    <ListBox x:Name="list" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="5" ItemsSource="{Binding}" ItemTemplate="{StaticResource itemTemplate}" />
</Grid>

后面的UserControl代码:

    public List<Vehicle> vehicleList = new List<Vehicle>();

    public CustomControl()
    {
        InitializeComponent();
        createSomeVehicles();
        list.DataContext = vehicleList;
    }

    public void createSomeVehicles()
    {
        Car newcar = new Car();
        newcar.doors = 5;
        newcar.ownerName = "mike";

        Bike newbike = new Bike();
        newbike.ownerName = "dave";

        vehicleList.Add(newcar);
        vehicleList.Add(newbike);
    }

我希望能做什么:

我希望能够根据Vehicle对象的类型在列表对象中显示一个按钮。例如。我想在Open Boot的列表项中显示Car按钮;类型Bike没有启动,因此列表项中不会显示任何按钮。

想法如何实现这一点:

我根据它的对象类型研究了不同DataTemplates的自定义绑定。例如。从后面的代码我可以打电话:

object.Template = (ControlTemplate)control.Resources["templateForCar"];

这里的问题是我在整个列表中使用Binding,因此无法手动将DataTemplate绑定到每个列表项,列表绑定控制其项目的DataTemplate。

1 个答案:

答案 0 :(得分:5)

您可以为每个Bike and Car (以及任何CLR类型)创建DataTemplate。通过指定DataTemplate DataType 属性,只要WPF看到该类型,模板就会自动

<Grid>
    <Grid.Resources>
        <DataTemplate DataType="{x:Type local:Car}">
            <WrapPanel>
                <TextBlock Text="{Binding Path=ownerName}"/>
                <Button Content="Open Boot" ... />
            </WrapPanel>
        </DataTemplate>
        <DataTemplate DataType="{x:Type local:Bike}">
            <WrapPanel>
                <TextBlock Text="{Binding Path=ownerName}"/>
            </WrapPanel>
        </DataTemplate>
    </Grid.Resources>
    <ListBox x:Name="list" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="5" ItemsSource="{Binding}" />
</Grid>