Datatemplate can be used in WPF to assist in databinding on object sets. In addition, the datatype attribute of datatemplate allows different objects in the object set to have different appearances after databinding 」. A simple example is as follows: different vehicle types present different detailed data based on the vehicle type.
namespace BindingInterfaceSample{ public class Car { public string Name { get; set; } } public class Truck : Car { public int MaxLoad { get; set; } } public class Roadster : Car { public int MaxSpeed { get; set; } }}
<Window x:Class="BindingInterfaceSample.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:clk="clr-namespace:BindingInterfaceSample" Title="MainWindow" Height="350" Width="525"> <ItemsControl > <ItemsControl.Items> <clk:Truck Name="Truck01" MaxLoad="100" /> <clk:Truck Name="Truck02" MaxLoad="500" /> <clk:Roadster Name="Roadster01" MaxSpeed="99" /> </ItemsControl.Items> <ItemsControl.Resources> <DataTemplate DataType="{x:Type clk:Truck}"> <WrapPanel> <TextBlock Text="Truck" /> <TextBlock Text="{Binding Path=MaxLoad}" /> </WrapPanel> </DataTemplate> <DataTemplate DataType="{x:Type clk:Roadster}"> <WrapPanel> <TextBlock Text="Roadster" /> <TextBlock Text="{Binding Path=MaxSpeed}" /> </WrapPanel> </DataTemplate> </ItemsControl.Resources> </ItemsControl></Window>
Likewise, you can also use the ype attribute of datatemplate to make different objects in the object set have the "same appearance" after databinding 」. A simple example is as follows: as long as the vehicle is used, only the vehicle data is displayed.
namespace BindingInterfaceSample{ public class Car { public string Name { get; set; } } public class Truck : Car { public int MaxLoad { get; set; } } public class Roadster : Car { public int MaxSpeed { get; set; } }}
<Window x:Class="BindingInterfaceSample.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:clk="clr-namespace:BindingInterfaceSample" Title="MainWindow" Height="350" Width="525"> <ItemsControl > <ItemsControl.Items> <clk:Truck Name="Truck01" MaxLoad="100" /> <clk:Truck Name="Truck02" MaxLoad="500" /> <clk:Roadster Name="Roadster01" MaxSpeed="99" /> </ItemsControl.Items> <ItemsControl.Resources> <DataTemplate DataType="{x:Type clk:Car}"> <Button Content="{Binding Path=Name}" /> </DataTemplate> </ItemsControl.Resources> </ItemsControl></Window>
In addition, different objects in the object set can have the "same appearance" after databinding 」. In this scenario, if datatemplate's ype is set to interface type, unexpected execution results will appear in WPF. A simple example is as follows: if ype is set to interface type, it cannot correspond to datatemplate.
namespace BindingInterfaceSample{ public interface ICar { string Name { get; set; } } public class Truck : ICar { public string Name { get; set; } public int MaxLoad { get; set; } } public class Roadster : ICar { public string Name { get; set; } public int MaxSpeed { get; set; } }}
<Window x:Class="BindingInterfaceSample.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:clk="clr-namespace:BindingInterfaceSample" Title="MainWindow" Height="350" Width="525"> <ItemsControl > <ItemsControl.Items> <clk:Truck Name="Truck01" MaxLoad="100" /> <clk:Truck Name="Truck02" MaxLoad="500" /> <clk:Roadster Name="Roadster01" MaxSpeed="99" /> </ItemsControl.Items> <ItemsControl.Resources> <DataTemplate DataType="{x:Type clk:ICar}"> <Button Content="{Binding Path=Name}" /> </DataTemplate> </ItemsControl.Resources> </ItemsControl></Window>
If the ype of the datatemplate must be set to the interface type. The solution is simple: rewrite the data to fasten the datatemplateselector used by the container, add an index based on the interface type, query the datatemplate in the resource, and use this datatemplate for databinding. A simple example is as follows: as long as there is an actual vehicle interface, only the vehicle data is displayed.
namespace BindingInterfaceSample{ public interface ICar { string Name { get; set; } } public class Truck : ICar { public string Name { get; set; } public int MaxLoad { get; set; } } public class Roadster : ICar { public string Name { get; set; } public int MaxSpeed { get; set; } }}
<Window x:Class="BindingInterfaceSample.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:clk="clr-namespace:BindingInterfaceSample" Title="MainWindow" Height="350" Width="525"> <ItemsControl> <ItemsControl.Items> <clk:Truck Name="Truck01" MaxLoad="100" /> <clk:Truck Name="Truck02" MaxLoad="500" /> <clk:Roadster Name="Roadster01" MaxSpeed="99" /> </ItemsControl.Items> <ItemsControl.Resources> <DataTemplate DataType="{x:Type clk:ICar}"> <Button Content="{Binding Path=Name}" /> </DataTemplate> </ItemsControl.Resources> <ItemsControl.ItemTemplateSelector> <clk:StandardDataTemplateSelector /> </ItemsControl.ItemTemplateSelector> </ItemsControl></Window>
namespace BindingInterfaceSample{ public class StandardDataTemplateSelector : DataTemplateSelector { // Methods public override DataTemplate SelectTemplate(object item, DependencyObject container) { #region Require if (item == null) throw new ArgumentNullException(); if (container == null) throw new ArgumentNullException(); #endregion // Result DataTemplate itemDataTemplate = null; // Base DataTemplate itemDataTemplate = base.SelectTemplate(item, container); if (itemDataTemplate != null) return itemDataTemplate; // Interface DataTemplate FrameworkElement itemContainer = container as FrameworkElement; if (itemContainer == null) return null; foreach (Type itemInterface in item.GetType().GetInterfaces()) { itemDataTemplate = itemContainer.TryFindResource(new DataTemplateKey(itemInterface)) as DataTemplate; if (itemDataTemplate != null) break; } // Return return itemDataTemplate; } }}
Reference data
Style, datatemplate, and implicit index key
Datatemplatekey category
Model column download
Bindinginterfacesample click here to download