Conditional DataTemplates when binding to a collection

那年仲夏 提交于 2019-12-08 07:51:12

问题


Sample Application:

The sample application that the supplied code belongs to displays a list of Vehicle objects via Binding. The Vehicle class is a top level class that subclasses can derive from e.g. Car and Bike. The sample application at the moment displays the owner's name of the Vehicle.

Sample Model code:

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

<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 code behind:

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

What I want to be able to do:

I would like to be able to display a button in the list object dependant upon the Type of the Vehicle object. E.g. I would like to display a Open Boot button within the list item for Car's; Type Bike does not have a boot and so no button would display within the list item.

Idea's on how to accomplish this:

I have looked into the custom binding of different DataTemplates based upon what type of object it is. E.g. from the code behind I could call:

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

The problem here is that I am using a Binding on the whole list and so there is no way to manually bind a DataTemplate to each of the list items, the list binding controls the DataTemplate of it's items.


回答1:


You can create a DataTemplate for each Bike and Car (and for any CLR type). By specifying the DataTemplate's DataType property, the template will automatically be applied whenever WPF sees that type.

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


来源:https://stackoverflow.com/questions/8344037/conditional-datatemplates-when-binding-to-a-collection

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