2011-05-09 2 views
4

DataGridTemplateColumn에 적용되는 DataTemplateSelector가 있습니다. 다른 열의 DataRow의 특정 정보에 따라 달라지는 DataTemplate이 올바르게 제공됩니다.WPF DataTemplateSelector 기준이 변경되었지만 템플릿이 다시 적용되지 않습니다?

지금까지 그렇게 좋았습니다.

그러나 이제 다른 데이터 템플릿이 해당 열의 선택기로 선택되도록하는 표의 데이터를 변경하면이 새 DataTemplate이 자동으로 표시되지 않습니다.

Matthew MacDonald (Apress) 페이지 564에있는 C# 2008의 Pro WPF에서이 문제가 알려져 있으며 Selector를 릴리스하고 다시 적용하는 방법은 내 레코드에 많은 레코드가있을 때 매우 느릴 수 있습니다. 표.

이 문제를 해결할 방법을 찾은 사람이 있습니까, 아니면 .NET4에이 문제를 해결할 수있는 새로운 기능이 있습니까?

감사

마르셀

답변

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; 
    } 
} 

편집 : 나는 선택 대신 변환기를 사용하는 것이었다 내 이전 대답을 제거했습니다. 그게 효과가 있었지만 이것이 더 나은 대답이라고 생각합니다.

관련 문제