WPF中的TemplateSelector通过在运行时根据数据对象动态选择DataTemplate,提升了UI的灵活性和可维护性。它解耦了数据与视图逻辑,支持复杂业务判断,便于代码复用,并使UI结构更清晰。实现时需定义DataTemplate、创建继承DataTemplateSelector的类并重写SelectTemplate方法,结合属性绑定和XAML资源引用。相比基于DataType的隐式模板、DataTrigger或Converter等纯XAML方案,TemplateSelector更适合多条件、多模板的复杂场景,是处理动态UI呈现的高效解决方案。

WPF中的
TemplateSelector
DataTemplate
TemplateSelector
要使用
TemplateSelector
DataTemplateSelector
SelectTemplate
DataTemplate
首先,你需要定义好你可能会用到的所有
DataTemplate
Window.Resources
UserControl.Resources
x:Key
<Window.Resources>
<DataTemplate x:Key="UrgentTaskTemplate">
<Border Background="Red" Margin="2" Padding="5">
<TextBlock Text="{Binding Title}" Foreground="White" FontWeight="Bold"/>
</Border>
</DataTemplate>
<DataTemplate x:Key="NormalTaskTemplate">
<Border Background="LightBlue" Margin="2" Padding="5">
<TextBlock Text="{Binding Title}" Foreground="DarkBlue"/>
</Border>
</DataTemplate>
<DataTemplate x:Key="CompletedTaskTemplate">
<Border Background="LightGreen" Margin="2" Padding="5">
<StackPanel Orientation="Horizontal">
<TextBlock Text="✔ " Foreground="Green"/>
<TextBlock Text="{Binding Title}" TextDecorations="Strikethrough" Foreground="Gray"/>
</StackPanel>
</Border>
</DataTemplate>
</Window.Resources>接下来,创建一个自定义的
TemplateSelector
TaskItem
Status
using System.Windows;
using System.Windows.Controls;
public class TaskTemplateSelector : DataTemplateSelector
{
public DataTemplate UrgentTemplate { get; set; }
public DataTemplate NormalTemplate { get; set; }
public DataTemplate CompletedTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
if (item is TaskItem task)
{
switch (task.Status)
{
case TaskStatus.Urgent:
return UrgentTemplate;
case TaskStatus.Completed:
return CompletedTemplate;
default:
return NormalTemplate;
}
}
return base.SelectTemplate(item, container); // Fallback
}
}
// 示例数据模型
public class TaskItem
{
public string Title { get; set; }
public TaskStatus Status { get; set; }
}
public enum TaskStatus
{
Normal,
Urgent,
Completed
}注意,这里我把
DataTemplate
TaskTemplateSelector
最后,在你的XAML中实例化这个自定义的
TemplateSelector
ItemsControl
ListBox
ListView
ItemTemplateSelector
ContentControl
ContentTemplateSelector
<Window x:Class="WpfApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApp" <!-- 确保命名空间正确 -->
Title="任务列表" Height="450" Width="800">
<Window.Resources>
<!-- DataTemplates如上所示 -->
<DataTemplate x:Key="UrgentTaskTemplate">...</DataTemplate>
<DataTemplate x:Key="NormalTaskTemplate">...</DataTemplate>
<DataTemplate x:Key="CompletedTaskTemplate">...</DataTemplate>
<!-- 实例化你的TemplateSelector -->
<local:TaskTemplateSelector x:Key="MyTaskSelector"
UrgentTemplate="{StaticResource UrgentTaskTemplate}"
NormalTemplate="{StaticResource NormalTaskTemplate}"
CompletedTemplate="{StaticResource CompletedTaskTemplate}"/>
</Window.Resources>
<Grid>
<ListBox ItemsSource="{Binding Tasks}"
ItemTemplateSelector="{StaticResource MyTaskSelector}"/>
</Grid>
</Window>在后台代码中,你需要设置
DataContext
Tasks
public partial class MainWindow : Window
{
public ObservableCollection<TaskItem> Tasks { get; set; }
public MainWindow()
{
InitializeComponent();
Tasks = new ObservableCollection<TaskItem>
{
new TaskItem { Title = "完成项目报告", Status = TaskStatus.Urgent },
new TaskItem { Title = "回复邮件", Status = TaskStatus.Normal },
new TaskItem { Title = "安排会议", Status = TaskStatus.Urgent },
new TaskItem { Title = "购买咖啡豆", Status = TaskStatus.Completed },
new TaskItem { Title = "学习WPF新特性", Status = TaskStatus.Normal }
};
this.DataContext = this;
}
}这样,当
ListBox
TaskItem
TaskTemplateSelector
TaskItem
Status
DataTemplate
从我个人的经验来看,
TemplateSelector
首先,解耦了数据和视图的呈现逻辑。以前,如果想根据数据状态改变UI,你可能得写一堆
DataTrigger
Style
Converter
Trigger
TemplateSelector
其次,它支持更复杂的业务逻辑判断。
DataTrigger
TemplateSelector
SelectTemplate
Trigger
再者,提高了代码的复用性。一旦你编写了一个通用的
TemplateSelector
UserStatusTemplateSelector
TemplateSelector
最后,它让UI结构更清晰。当一个
ItemsControl
TemplateSelector
DataTrigger
TemplateSelector
实现自定义
TemplateSelector
关键步骤回顾(略有补充):
DataTemplate
x:Key
DataTemplateSelector
DataTemplateSelector
DataTemplate
DataTemplate
SelectTemplate(object item, DependencyObject container)
item
TaskItem
container
ListBoxItem
ContentPresenter
item
DataTemplate
null
item
null
SelectTemplate
null
DataTemplate
DataType
ToString()
TemplateSelector
ItemsControl
ItemTemplateSelector
ContentControl
ContentTemplateSelector
注意事项:
SelectTemplate
SelectTemplate
DataTemplate
TemplateSelector
SelectTemplate
container.FindResource()
Application.Current.FindResource()
SelectTemplate
item
SelectTemplate
TemplateSelector
d:DataContext
DependencyObject container
ListBoxItem
VisualTreeHelper
item
在我看来,掌握这些,你就能游刃有余地使用
TemplateSelector
TemplateSelector
基于DataType
DataTemplate
Resources
DataTemplate
x:Key
DataType="{x:Type local:YourDataType}"ContentPresenter
ItemsControl
DataTemplate
DataType
ObservableCollection<object>
Person
Company
Person
Company
ContentControl.ContentTemplate
DataTrigger
Converter
ContentControl
ContentTemplate
ContentControl
Style
DataTrigger
Content
ContentTemplate
Converter
Content
DataTemplate
x:Key
DynamicResource
StaticResource
ContentControl
User.IsOnline
DataTrigger
ItemsControl
ItemContainerStyle
ItemsControl.ItemContainerStyle
DataTrigger
ItemsControl
ListBox
ItemContainerStyle
ListBoxItem
Style
DataTrigger
ContentTemplate
ContentTemplate
ListBoxItem
在我看来,这几种方法各有侧重:
DataType
DataTrigger
ContentTemplate
TemplateSelector
ItemsControl
DataTrigger
TemplateSelector
选择哪种方法,最终还是取决于你的具体需求、团队的编码习惯以及对项目复杂度的预估。我个人在项目里,如果遇到超过两种模板切换,或者切换逻辑需要访问多个属性甚至外部状态时,几乎都会毫不犹豫地选择
TemplateSelector
以上就是WPF中的模板选择器TemplateSelector怎么用?的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号