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