4 Stimmen

Wie cellTemplateSelector auslösen, wenn Elemente geändert

Ich habe 2 Vorlagen für das CellTemplate von DataGrid. Wenn ich die Elemente ändern, wird es mir nicht helfen, wählen Sie die Vorlage für mich, meine DisplayModeTemplateSelector wird nicht einmal aufgerufen werden!

Was ich mich frage ist, wenn es eine Möglichkeit gibt, diese CellTemplateSelector wieder auslösen, wenn Elemente geändert? Wie aktualisiert man CellTemplate in DataGrid oder ListView, wenn sich der Inhalt ändert?

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

Ich habe diesen Blog gefunden http://dotdotnet.blogspot.com/2008/11/refresh-celltemplate-in-listview-when.html

Ich glaube, das ist ähnlich wie bei meinem Problem, aber ich kann ihn wirklich nicht verstehen! Kann mir das jemand erklären?

4voto

vortexwolf Punkte 13867

Die Lösung in diesem Blogbeitrag funktioniert nicht mit dem DataGrid Kontrolle, weil die DataGridTemplateColumn Klasse gehört nicht zum Visual Tree, und selbst als ich versuchte, sie an eine statische Klasse zu binden, hatte ich keinen Erfolg, weil nach Eigenschaftsänderungen seltsame Ausnahmen auftraten.

Es gibt jedoch zwei Möglichkeiten, dieses Problem zu lösen.

1) Der einfachere Weg.

Die Verwendung des ObservableCollection Klasse.

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

2) Der komplexere Weg.

Sie können Ihrer Elementklasse die Eigenschaft hinzufügen, die das Objekt selbst zurückgibt.

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

Danach können Sie die ContentControl.ContentTemplateSelector anstelle der CellTemplateSelector wie diese:

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

Und wenn Sie die Eigenschaft ändern, rufen Sie die Update Methode irgendwie:

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

Der Grund, warum ich einen Nullwert für die SelfProperty en el Update Methode ist zunächst, dass die Selector aktualisiert eine Vorlage erst, wenn die Content Eigenschaft vollständig verändert wird. Wenn ich dasselbe Objekt noch einmal einstelle, passiert nichts, aber wenn ich ihm zuerst einen Nullwert zuweise, werden die Änderungen verarbeitet.

2voto

TarkaDaal Punkte 17500

Der einfachste Weg ist, das Selection Changed-Ereignis der Combo Box zu haken und den Template-Selektor neu zuzuweisen. Dies erzwingt eine Aktualisierung.

In XAML (gehen Sie davon aus, dass der Rest des 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>

Das bezieht sich auf diese DataGridTemplateColumn:

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

Und in dem Code dahinter:

private void GateIDChanged(object sender, SelectionChangedEventArgs eventArgs)
{
    var selector = GateParamsColumn.CellTemplateSelector;
    GateParamsColumn.CellTemplateSelector = null;
    GateParamsColumn.CellTemplateSelector = selector;
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X