Как вызвать 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;
}