一种解决方案是将 ContentPresenter 放在单元格内。这样,当内容更改时,ContentPresenter 将再次从选择器请求模板。例如:
<Window
x:Class="TestSAS.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
xmlns:local="clr-namespace:TestSAS">
<Window.Resources>
<local:MySelector x:Key="mySelector">
<local:MySelector.UpperTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="upper - "></TextBlock>
<TextBlock Text="{Binding}"></TextBlock>
</StackPanel>
</DataTemplate>
</local:MySelector.UpperTemplate>
<local:MySelector.LowerTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="lower - "></TextBlock>
<TextBlock Text="{Binding}"></TextBlock>
</StackPanel>
</DataTemplate>
</local:MySelector.LowerTemplate>
</local:MySelector>
</Window.Resources>
<DockPanel>
<Button DockPanel.Dock="Bottom" Click="doit_Click">Do It</Button>
<DataGrid Name="mainGrid" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ContentPresenter Content="{Binding FirstName}" ContentTemplateSelector="{StaticResource mySelector}"></ContentPresenter>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</DockPanel>
</Window>
和后面的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
namespace TestSAS
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
mainGrid.ItemsSource = "Bob,mary,frank,George".Split(',').Select(s => new Person() { FirstName = s }).ToArray();
}
private void doit_Click(object sender, RoutedEventArgs e)
{
((Person[])mainGrid.ItemsSource)[2].FirstName = "Frank";
}
}
public class MySelector : DataTemplateSelector
{
public DataTemplate UpperTemplate { get; set; }
public DataTemplate LowerTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
var st = item as string;
if (st == null) return null;
if (st.Substring(0, 1).ToString().ToLower() == st.Substring(0, 1).ToString()) return LowerTemplate;
return UpperTemplate;
}
}
public class Person : INotifyPropertyChanged
{
private string firstName;
public string FirstName
{
get { return firstName; }
set
{
firstName = value;
if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("FirstName"));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
编辑:我已经删除了我之前的答案,即使用转换器而不是选择器。这确实有效,但我认为这是一个更好的答案。