若是把控件的功能視爲內容,則能夠使用控件模板 ControlTemplate 來控制它的展示;
若是把數據視爲內容,則能夠使用數據模板 DataTemplate 把數據展現出來;算法ControlTemplate 是算法內容的表現形式,一個控件怎樣組織其內部結構才讓它更符合業務邏輯、讓用戶操做起來更舒服就是由它來控制的;
DataTemplate 是數據內容的表現形式,一條數據是簡單的文本仍是圖形動畫仍是其餘,由它決定。express
<DataTemplate x:Key="dt"> <Grid> <StackPanel Orientation="Horizontal"> <Grid> <Rectangle Width="{Binding Price}" Fill="LightSalmon"/> <TextBlock Text="{Binding Year}"></TextBlock> </Grid> <TextBlock Text="{Binding Price}"></TextBlock> </StackPanel> </Grid> </DataTemplate>
ContentControl 的 ContentTemplate 屬性,給 ContentControl 的內容穿衣服;
ItemsControl 的 ItemTemplate 屬性,給 ItemsControl 的數據條目穿衣服;
GridViewColumn 的 CellTemplate 屬性,給 GridViewColumn 單元格里的數據穿衣服。動畫
<Window x:Class="WpfAppTemplate.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfAppTemplate" mc:Ignorable="d" Title="MainWindow" Height="350" Width="623"> <Window.Resources> <local:NameToPhotoPathConverter x:Key="nameToPhotoPathConverter"/> <!--集合條目的內容模板--> <DataTemplate x:Key="carListItemViewTemplate"> <Grid Margin="2"> <StackPanel Orientation="Horizontal"> <Image Height="60" Width="64" Source="{Binding Name, Converter={StaticResource nameToPhotoPathConverter}}" /> <StackPanel Margin="5 12"> <TextBlock Text="Name" FontWeight="Bold"/> <TextBlock Text="{Binding Name}"/> </StackPanel> </StackPanel> </Grid> </DataTemplate> <!--詳情的內容模板--> <DataTemplate x:Key="carDetailViewTemplate"> <Border BorderBrush="Black" BorderThickness="1" CornerRadius="6" Margin="2"> <StackPanel Margin="5"> <Image Height="250" Width="400" Source="{Binding Name, Converter={StaticResource nameToPhotoPathConverter}}" /> <StackPanel Orientation="Horizontal" Margin="5,0"> <TextBlock Text="Name:" FontWeight="Bold" FontSize="19"/> <TextBlock Text="{Binding Name}" FontSize="19"/> </StackPanel> <StackPanel Orientation="Horizontal" Margin="5 0"> <StackPanel Orientation="Horizontal"> <TextBlock Text="Year:" FontWeight="Bold"/> <TextBlock Text="{Binding Year}"/> </StackPanel> <StackPanel Orientation="Horizontal" Margin="5 0"> <TextBlock Text="TopSpeed:" FontWeight="Bold"/> <TextBlock Text="{Binding TopSpeed}"/> </StackPanel> </StackPanel> </StackPanel> </Border> </DataTemplate> </Window.Resources> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="5*"/> <ColumnDefinition Width="2*"/> </Grid.ColumnDefinitions> <UserControl x:Name="carDetailControl" ContentTemplate="{StaticResource carDetailViewTemplate}" Content="{Binding ElementName=listBoxCar, Path=SelectedItem}" /> <ListBox Grid.Column="1" x:Name="listBoxCar" Margin="2" ItemTemplate="{StaticResource carListItemViewTemplate}" /> </Grid> </Window> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); InitializeList(); } /// <summary> /// 添加汽車種類 /// </summary> void InitializeList() { List<Car> carList = new List<Car>(); carList.Add(new Car() { Name = "BMW", TopSpeed = "260", Year = "1997" }); carList.Add(new Car() { Name = "Audi", TopSpeed = "240", Year = "1999" }); carList.Add(new Car() { Name = "Toyota", TopSpeed = "120", Year = "2016" }); carList.Add(new Car() { Name = "Volkswagen", TopSpeed = "150", Year = "2000" }); this.listBoxCar.ItemsSource = carList; } }
使用 winform 的 Usercontrol 實現一個汽車列表和詳情this
<!--汽車詳情--> <UserControl x:Class="WpfAppTemplate.UserControls.CarDetailUserControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WpfAppTemplate.UserControls" mc:Ignorable="d" > <Border BorderBrush="Black" BorderThickness="1" CornerRadius="6" Margin="2"> <StackPanel Margin="5"> <Image x:Name="img" Height="250" Width="400"/> <StackPanel Orientation="Horizontal" Margin="5,0"> <TextBlock Text="Name:" FontWeight="Bold" FontSize="19"/> <TextBlock x:Name="textBlockName" FontSize="19"/> </StackPanel> <StackPanel Orientation="Horizontal" Margin="5 0"> <StackPanel Orientation="Horizontal"> <TextBlock Text="Year:" FontWeight="Bold"/> <TextBlock x:Name="textBlockYear"/> </StackPanel> <StackPanel Orientation="Horizontal" Margin="5 0"> <TextBlock Text="TopSpeed:" FontWeight="Bold"/> <TextBlock x:Name="textBlockTopSpeed"/> </StackPanel> </StackPanel> </StackPanel> </Border> </UserControl> public partial class CarDetailUserControl : UserControl { public CarDetailUserControl() { InitializeComponent(); } Car _currentCar; public Car CurrentCar { get { return _currentCar; } set { if (value == null) return; _currentCar = value; this.textBlockName.Text = value.Name; this.textBlockTopSpeed.Text = value.TopSpeed; this.textBlockYear.Text = value.Year; string uriStr = string.Format(@"/Resources/Images/Cars/{0}.jpg", value.Name); this.img.Source = new BitmapImage(new Uri(uriStr, UriKind.Relative)); } } } <!--汽車條目--> <UserControl x:Class="WpfAppTemplate.UserControls.CarListItemUserControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WpfAppTemplate.UserControls" mc:Ignorable="d"> <Grid Margin="2"> <StackPanel Orientation="Horizontal"> <Image x:Name="img" Height="60" Width="64"/> <StackPanel Margin="5 12"> <TextBlock Text="Name" FontWeight="Bold"/> <TextBlock x:Name="textBlockName" /> </StackPanel> </StackPanel> </Grid> </UserControl> public partial class CarListItemUserControl : UserControl { public CarListItemUserControl() { InitializeComponent(); } Car _currentCar; public Car CurrentCar { get { return _currentCar; } set { if (value == null) return; _currentCar = value; this.textBlockName.Text = value.Name; string uriStr = string.Format(@"/Resources/Images/Cars/{0}.jpg", value.Name); this.img.Source = new BitmapImage(new Uri(uriStr, UriKind.Relative)); } } } <!--主窗體--> <Window x:Class="WpfAppTemplate.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfAppTemplate" xmlns:localUserControls="clr-namespace:WpfAppTemplate.UserControls" mc:Ignorable="d" Title="MainWindow" Height="350" Width="623"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="5*"/> <ColumnDefinition Width="2*"/> </Grid.ColumnDefinitions> <localUserControls:CarDetailUserControl x:Name="carDetailControl"/> <ListBox Grid.Column="1" x:Name="listBoxCar" SelectionChanged="listBoxCar_SelectionChanged" Margin="2"/> </Grid> </Window> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); InitializeList(); } /// <summary> /// 添加汽車種類 /// </summary> void InitializeList() { List<Car> carList = new List<Car>(); carList.Add(new Car() { Name = "BMW", TopSpeed = "260", Year = "1997" }); carList.Add(new Car() { Name = "Audi", TopSpeed = "240", Year = "1999" }); carList.Add(new Car() { Name = "Toyota", TopSpeed = "120", Year = "2016" }); carList.Add(new Car() { Name = "Volkswagen", TopSpeed = "150", Year = "2000" }); // 給每種汽車生成一個 汽車條目控件,做爲一條內容添加到汽車列表控件的內容集合 foreach (Car car in carList) { CarListItemUserControl control = new CarListItemUserControl(); control.CurrentCar = car; this.listBoxCar.Items.Add(control); } } /// <summary> /// 當切換汽車時 /// </summary> /// <param name="sender">listbox</param> /// <param name="e">SelectionChangedEventArgs, 能夠經過 AddedItems 參數取到新選擇的項</param> private void listBoxCar_SelectionChanged(object sender, SelectionChangedEventArgs e) { CarListItemUserControl control = e.AddedItems[0] as CarListItemUserControl; if (control != null) { this.carDetailControl.CurrentCar = control.CurrentCar; } } }