如何在Items更改时触发cellTemplateSelector

时间:2011-09-25 01:25:58

标签: wpf templates xaml triggers celltemplate

我有2个模板用于DataGrid的CellTemplate。当我更改项目时,它不会帮助我为我选择模板,甚至不会调用我的DisplayModeTemplateSelector!

我想知道的是,当项目发生变化时,是否有办法再次触发此CellTemplateSelector?如何在内容更改时刷新DataGrid或ListView中的CellTemplate

<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 个答案:

答案 0 :(得分:3)

博客文章中的解决方案不适用于DataGrid控件,因为DataGridTemplateColumn类不属于Visual Tree,即使我尝试将其绑定到静态类,在财产变更后,我没有因为奇怪的例外而成功。

无论如何,有两种方法可以解决这个问题。

1)更简单的方法。

使用ObservableCollection类。

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

2)更复杂的方式。

您可以向item类添加返回对象本身的属性。

    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设置空值的原因是SelectorContent之前不会更新模板财产完全改变了。如果我再次设置相同的对象 - 什么都不会发生,但如果我首先为它设置一个空值 - 将会处理更改。

答案 1 :(得分:2)

简单的方法是挂钩组合框的选择更改事件,并重新分配模板选择器。这会强制刷新。

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