## 模板概述
**ControlTemplate** - 定义控件的视觉结构**DataTemplate** - 定义数据的显示方式
## ControlTemplate
### 基本概念
ControlTemplate 替换控件的默认视觉结构:<Windowxmlns:https://github.com/avaloniaui"> <Window.Styles> <StyleSelector="Button.custom"> <SetterProperty="Template"> <ControlTemplate> <BorderBackground="Blue"CornerRadius="15"> <ContentPresenterContent="{TemplateBinding Content}"/> </Border> </ControlTemplate> </Setter> </Style> </Window.Styles> <ButtonClasses="custom"Content="Custom Button"/></Window>
### TemplateBinding
<ControlTemplate> <BorderBackground="{TemplateBinding Background}" CornerRadius="{TemplateBinding CornerRadius}"> <ContentPresenterContent="{TemplateBinding Content}"/> </Border></ControlTemplate>
## DataTemplate
### 基本概念
<ListBoxItemsSource="{Binding Users}"> <ListBox.ItemTemplate> <DataTemplate> <StackPanelOrientation="Horizontal"> <TextBlockText="{Binding Name}"/> <TextBlockText="{Binding Age}"Margin="10,0,0,0"/> </StackPanel> </DataTemplate> </ListBox.ItemTemplate></ListBox>
## 数据类型模板
### Typed DataTemplate
public class UserTemplate : DataTemplate{ public override Control Build(object? data) { return new UserCard { User = data as UserModel }; } public override bool Match(object? data) { return data is UserModel; }}
### 注册模板
<Windowxmlns:local="clr-namespace:MyApp"> <Window.Resources> <local:UserTemplatex:Key="UserTemplate"/> </Window.Resources> <ListBoxItemTemplates="{Binding UserTemplate}"/></Window>
## 模板选择器
### DataTemplateSelector
public class StatusTemplateSelector : IDataTemplateSelector{ public ITemplate<Control>? this[Type dataType] => null; public Control? Build(object? data, Control scope, IDataTemplateHost? host) { if (data is OrderModel order) { return order.Status switch { OrderStatus.Pending => new PendingOrderTemplate(), OrderStatus.Completed => new CompletedOrderTemplate(), _ => new DefaultOrderTemplate() }; } return new TextBlock { Text = "Unknown" }; } public bool Match(object? data, Control scope, IDataTemplateHost? host) { return data is OrderModel; }}
## 模板中的控件
### ContentPresenter
<ControlTemplate> <StackPanel> <TextBlockText="Title"/> <ContentPresenterContent="{TemplateBinding Content}"/> </StackPanel></ControlTemplate>
### ItemsPresenter
<ControlTemplate> <Border> <ItemsPresenter/> </Border></ControlTemplate>
## 样式 vs 模板
| 方面 | Style | ControlTemplate ||-----|-------|----------------|| 用途 | 设置属性 | 定义视觉结构 || 粒度 | 细粒度 | 粗粒度 || 灵活性 | 有限 | 完整替换 || 性能 | 轻量 | 较重 |
需要完全替换控件外观需要添加额外的视觉元素样式无法满足需求
## 总结
| 模板 | 用途 ||-----|------|| ControlTemplate | 定义控件的视觉结构 || DataTemplate | 定义数据的展示方式 || DataTemplateSelector | 动态选择模板 |
模板替换整个视觉结构数据模板控制列表项显示模板选择器实现条件渲染
## 下期预告
下一篇文章我们将开始 **实战项目** 系列,用 Todo List 应用从设计到实现。