我有一个DataTemplateSelector应用于DataGridTemplateColumn。 它正确地为我提供了一个DataTemplate,它根据我的DataRow中的某些信息而变化(在其他列中)。
到目前为止一切顺利。
但是,当我现在更改网格中的数据时,会导致该列的选择器选择不同的DataTemplate,它不会自动显示这个新的DataTemplate。
我在Matthew MacDonald(Apress)第564页的C#2008中阅读Pro WPF,这是已知的问题,唯一的方法是释放Selector并重新应用这个,当我的表中有很多记录时这将非常慢
有没有人找到解决方法或者在.NET4中有一个新功能可以解决这个问题?
由于
马塞尔
答案 0 :(得分:3)
一种解决方案是将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;
}
}
编辑:我删除了之前的答案,即使用转换器而不是选择器。这确实有效,但我认为这是一个更好的答案。