1. 新建DataTemplateSelectorDemo的WPF项目
项目布局如下:
2. App.xaml
<unity:PrismApplication x:Class="DataTemplateSelectorDemo.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:unity="http://prismlibrary.com/"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application.Resources />
</unity:PrismApplication>
3. App.xaml.cs
using DataTemplateSelectorDemo.Views;
using Prism.Ioc;
using System.Windows;
namespace DataTemplateSelectorDemo
{
public partial class App
{
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
}
protected override Window CreateShell()
{
return this.Container.Resolve<MainWindowView>();
}
}
}
4. BooleanBrushConverter.cs
using System;
using System.Globalization;
using System.Windows.Data;
using System.Windows.Media;
namespace DataTemplateSelectorDemo.Common
{
[ValueConversion(typeof(bool), typeof(Brush))]
public class BooleanBrushConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is null)
throw new ArgumentNullException(nameof(value));
return (bool)value ? Brushes.LightGreen : Brushes.Red;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
5. CustomedTemplateSelector.cs
using System.Windows;
using System.Windows.Controls;
namespace DataTemplateSelectorDemo.Common
{
public class CustomedTemplateSelector : DataTemplateSelector
{
public DataTemplate FoundTemplate { get; set; }
public DataTemplate NotFoundTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
return item is null ? this.NotFoundTemplate
: item is not Info ? this.NotFoundTemplate
: (item as Info).TemplateSwitch ? this.FoundTemplate
: this.NotFoundTemplate;
}
}
}
6. Info.cs
using Prism.Mvvm;
namespace DataTemplateSelectorDemo
{
public class Info : BindableBase
{
private byte index;
private bool isSelected;
private string name;
private bool templateSwitch;
public byte Index
{
get => this.index;
set => this.SetProperty(ref this.index, value);
}
public bool IsSelected
{
get => this.isSelected;
set
{
if (this.SetProperty(ref this.isSelected, value))
{
System.Console.WriteLine(" The property of IsSelected is changed.");
}
}
}
public string Name
{
get => this.name;
set => this.SetProperty(ref this.name, value);
}
public bool TemplateSwitch
{
get => this.templateSwitch;
set => this.SetProperty(ref this.templateSwitch, value);
}
}
}
7. MainWindowViewModel.cs
using System.Collections.ObjectModel;
namespace DataTemplateSelectorDemo.ViewModels
{
public class MainWindowViewModel
{
public ObservableCollection<Info> InfoCollection { get; } = new ObservableCollection<Info>();
public MainWindowViewModel()
{
this.InfoCollection.Add(new Info() { Index = 1, Name = "1111", IsSelected = true, TemplateSwitch = false });
this.InfoCollection.Add(new Info() { Index = 2, Name = "2222", IsSelected = true, TemplateSwitch = true });
this.InfoCollection.Add(new Info() { Index = 3, Name = "3333", IsSelected = false, TemplateSwitch = false });
this.InfoCollection.Add(new Info() { Index = 4, Name = "4444", IsSelected = false, TemplateSwitch = true });
}
}
}
8. MainWindowView.xaml
<Window x:Class="DataTemplateSelectorDemo.Views.MainWindowView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:common="clr-namespace:DataTemplateSelectorDemo.Common"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:prism="http://prismlibrary.com/"
Title="MainWindow" Width="800" Height="450"
prism:ViewModelLocator.AutoWireViewModel="True" mc:Ignorable="d">
<!-- 指定ColumnWidth="*"使得列完整填充,且等分 -->
<DataGrid Margin="10" AutoGenerateColumns="False" CanUserAddRows="False" ColumnWidth="*" HeadersVisibility="Column" ItemsSource="{Binding Path=InfoCollection}">
<DataGrid.Resources>
<common:BooleanBrushConverter x:Key="BooleanBrushConverter" />
<DataTemplate x:Key="FoundTemplate">
<TextBlock FontSize="20" Foreground="LightGreen" Text="◉" />
</DataTemplate>
<DataTemplate x:Key="NotFoundTemplate">
<TextBlock FontSize="20" Foreground="Red" Text="◉" />
</DataTemplate>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=Index}" Header="索引" />
<DataGridTextColumn Binding="{Binding Path=Name}" Header="名称" />
<DataGridTemplateColumn Header="属性转换器">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock FontSize="20" Foreground="{Binding TemplateSwitch, Converter={StaticResource BooleanBrushConverter}}" Text="◉" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="数据触发器">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<TextBlock Name="found" FontSize="20" Foreground="LightGreen" Text="◉" />
<TextBlock Name="nofound" FontSize="20" Foreground="Red" Text="◉" />
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding TemplateSwitch}" Value="True">
<Setter TargetName="found" Property="Visibility" Value="Visible" />
<Setter TargetName="nofound" Property="Visibility" Value="Collapsed" />
</DataTrigger>
<DataTrigger Binding="{Binding TemplateSwitch}" Value="False">
<Setter TargetName="found" Property="Visibility" Value="Collapsed" />
<Setter TargetName="nofound" Property="Visibility" Value="Visible" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="模板选择器">
<DataGridTemplateColumn.CellTemplateSelector>
<common:CustomedTemplateSelector FoundTemplate="{StaticResource FoundTemplate}" NotFoundTemplate="{StaticResource NotFoundTemplate}" />
</DataGridTemplateColumn.CellTemplateSelector>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="选择与否">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<!-- 需要指定UpdateSourceTrigger属性才能在后端接收到界面值改变 -->
<RadioButton GroupName="Reference" IsChecked="{Binding Path=IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Window>
9. MainWindowView.xaml.cs
namespace DataTemplateSelectorDemo.Views
{
public partial class MainWindowView
{
public MainWindowView()
{
this.InitializeComponent();
}
}
}