Как вызвать cellTemplateSelector при изменении элементов

У меня есть 2 шаблона для CellTemplate DataGrid. Когда я изменяю элементы, это не поможет мне выбрать шаблон для меня, мой DisplayModeTemplateSelector даже не будет вызываться!

Что мне интересно, есть ли способ вызвать этот CellTemplateSelector снова, когда элементы изменились? Как обновить CellTemplate в DataGrid или ListView при изменении содержимого

<DataGridTemplateColumn x:Name="colorRange"
                        Width="*"
                        Header="Color Range">
    <DataGridTemplateColumn.CellTemplateSelector>
        <local:DisplayModeTemplateSelector HeatMapTemplate="{StaticResource heatMapTemplate}" ThreshHoldTemplate="{StaticResource threshHoldTemplate}" />
    </DataGridTemplateColumn.CellTemplateSelector>
</DataGridTemplateColumn>

Я нашел этот блог http://dotdotnet.blogspot.com/2008/11/refresh-celltemplate-in-listview-when.html

Я думаю, что это похоже на мою проблему, но я действительно не могу понять его! Кто-нибудь может это объяснить?

2 ответа

Решение

Решение в блоге не будет работать с DataGrid контролировать, потому что DataGridTemplateColumn класс не принадлежит к дереву визуалов, и даже когда я пытался связать его со статическим классом, я не добился успеха из-за странных исключений после изменения свойств.

В любом случае есть два возможных способа решения этой проблемы.

1) Более простой способ.

С использованием ObservableCollection учебный класс.

    var itemIndex = 0;
    var currentItem = vm.Items[itemIndex];
    //Change necessary properties
    //..
    vm.Items.Remove(currentItem);
    vm.Items.Insert(itemIndex, currentItem);      

2) Более сложный способ.

Вы можете добавить в свой класс элементов свойство, которое возвращает сам объект.

    public ItemViewModel(/*...*/)
    {
        this.SelfProperty = this;
        //...
    }

    public ItemViewModel SelfProperty { get; private set; }

    public void Update()
    {
        this.SelfProperty = null;
        this.OnPropertyChanged("SelfProperty");
        this.SelfProperty = this;
        this.OnPropertyChanged("SelfProperty");
    }

После этого вы можете использовать ContentControl.ContentTemplateSelector вместо CellTemplateSelector как это:

            <DataGridTemplateColumn Header="Color Range">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ContentControl Content="{Binding SelfProperty}"  ContentTemplateSelector="{StaticResource mySelector}" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>

И когда вы меняете свойство, звоните Update метод как-то:

  currentItem.SomeDataProperty = "some new value";
  //Or you can add this method call to the OnPropertyChanged 
  //so that it calls authomatically
  currentItem.Update(); 

Причина, по которой я установил нулевое значение SelfProperty в Update Во-первых, это то, что Selector не будет обновлять шаблон до Content свойство полностью изменено. Если я установлю тот же объект еще раз - ничего не произойдет, но если я сначала установлю нулевое значение для него - изменения будут обработаны.

Самый простой способ - перехватить событие "Выбор измененного" в поле со списком и переназначить селектор шаблона. Это заставляет освежиться.

В XAML (предположим, что остальная часть DataGrid/ComboBoxColumn:

<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="ComboBox">
    <Setter Property="ItemsSource" 
            Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}},  Path=DataContext.Gates, UpdateSourceTrigger=PropertyChanged}"/>
    <EventSetter Event="SelectionChanged" Handler="GateIDChanged" />
</Style>

Это относится к этому DataGridTemplateColumn:

<DataGridTemplateColumn x:Name="GateParamsColumn" Header="Gate Parameters" CellTemplateSelector="{StaticResource GateParamsTemplateSelector}"></DataGridTemplateColumn>

И в коде позади:

private void GateIDChanged(object sender, SelectionChangedEventArgs eventArgs)
{
    var selector = GateParamsColumn.CellTemplateSelector;
    GateParamsColumn.CellTemplateSelector = null;
    GateParamsColumn.CellTemplateSelector = selector;
}
Другие вопросы по тегам