控件模版
作用:定义自定义控件的视觉结构,分离自定义控件的逻辑和UI
这样一个功能控件,可以对应多个视觉结构。
如何使用
- 创建一个自定义控件
1
2
3
4
| public class CardView : ContentView
{
// No any visual structure
}
|
- 使用控件模板定义控件的UI,可以内联定义,以静态资源的形式
1
2
3
4
5
6
7
| <ContentPage.Resources>
<ControlTemplate :key="CardViewControlTemplate">
<Frame BindingContext="{Binding Source={RelativeSource TemplateParent}}"
BackgroundColor="{Binding CardColor}"
></Frame>
</ControlTemplate>
</ContentPage.Resources>
|
- 在使用自定义控件类时,将控件模板应用到该控件。
1
2
3
4
5
| <StackLayout>
<controls:CardView CardColor="White"
CardTitle="xxx"
ControlTemplate="{StaticResource CardViewControlTemplate}" />
</StackLayout>
|
其他小技巧
- 使用
TemplateBinding
替代模板绑定。 - 使用
Style
绑定控件模板 - 可以再定义一个兼容自定义控件的控件模板,来实现不同视觉样式。
ContentPresenter
实现类似插槽的功能。- 在使用到自定义控件的页面,可以使用
OnApplyTemplate()
钩子,在模板加载完成后,执行一些动作,例如调用GetTemplateChild
来获取模版中命名的组件。
数据模板
作用:自定义数据类型的展示格式,一种典型的使用方法,就是为CollectionView
等组件,配置ItemTemplate
的显示格式。
使用方法
- 内联方式,直接在需要使用模版的标签内部例如
ItemTemplate
中定义
1
2
3
4
5
6
7
8
9
10
11
12
| <CollectionView>
<CollectionView.ItemSource>
<!-- 定义一些数据源 -->
</CollectionView.ItemSource>
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid>
<Label Text="{Binding Name}" />
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
|
- 从
ContentView
派生强类型的数据模板。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| <ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="DataTemplates.PersonView">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.5*" />
<ColumnDefinition Width="0.2*" />
<ColumnDefinition Width="0.3*" />
</Grid.ColumnDefinitions>
<Label Text="{Binding Name}" FontAttributes="Bold" />
<Label Grid.Column="1" Text="{Binding Age}" />
<Label Grid.Column="2" Text="{Binding Location}" HorizontalTextAlignment="End" />
</Grid>
</ContentView>
|
- 以资源方式创建数据模板
1
2
3
4
5
6
7
| <ContentPage.Resources>
<DataTemplate x:Key="personTemplate">
<Grid>
...
</Grid>
</DataTemplate>
</ContentPage.Resources>
|
- 数据模板选择器,动态的选择不同的模板
public class PersonDataTemplateSelector : DataTemplateSelector
{
public DataTemplate ValidTemplate { get; set; }
public DataTemplate InvalidTemplate { get; set; }
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
{
return ((Person)item).DateOfBirth.Year >= 1980 ? ValidTemplate : InvalidTemplate;
}
}
1
2
3
4
5
6
7
8
| <ContentPage.Resources>
<DataTemplate x:Key="template1"></DataTemplate>
<DataTemplate x:Key="template2"></DataTemplate>
<local:PersonDataTemplateSelector x:Key="selector"
ValidTemplate="{}"
InvalidTemplate="{}"/>
</ContentPage.Resources>
<CollectionView ItemTemplate="{StaticRources selector}"/>
|
区别
数据模板和控件模板是完全不一样的。数据模板是继承自ContentView
的,是一种描述数据展示方式的特殊控件,而控件模板是一种静态资源。