2016-04-26 6 views
0

ändern Ich habe ein UserControl, in dem der Schlüssel visuelle Element wird wie folgt dargestellt:Bindung an Usercontrol Datacontext: update ContentTemplateSelector wenn einige Eigenschaften

<ContentPresenter Content="{Binding}" 
    ContentTemplateSelector="{StaticResource MStatusDisplaySelector}" /> 

Das DataContext dieses Element (dh das Bindungsziel) wird die UserControl selbst. Die MStatusDisplaySelector ist eine komplexe Selektor, und wählt eine DataTemplate auf der Grundlage mehrerer Eigenschaften dieses UserControl (die alle einfach sind DependencyProperty).

Das Problem ist, wenn eine dieser Eigenschaften ändern, muss möglicherweise eine andere Vorlage ausgewählt werden, und ich möchte die ContentPresenter aktualisieren. Dies geschieht offensichtlich nicht. Was ist der beste Weg, um dies zu umgehen?

Idealerweise würde Ich mag in jeder beteiligten Eigenschaftsänderung Rückrufe vermeiden umzusetzen. Nicht nur das ist zu ausführlich, sondern der Vorlagenselektor muss möglicherweise später eine andere Gruppe von Eigenschaften verwenden, und es ist nicht praktisch, dies synchron zu halten. Es ist jedoch wahrscheinlich in Ordnung, die Vorlage unter Eigenschaft Änderung zu aktualisieren.

P.S. Nehmen Sie an, dass die MStatusDisplaySelector Logiken zu kompliziert sind, um auf einen traditionellen Stil Selektor mit Style.Triggers reduziert werden. Ich möchte, dass es im Code-Behind bleibt.

+0

Klingt wie ein Stil-Trigger mit Setter, der die Vorlage, oder auch eine Vorlage Wähler ändern. Scheint etwas ungewöhnlich, die gesamte Vorlage bei Eigenschaftsänderungen zu ändern (normalerweise würden Sie Elemente der Vorlage basierend auf Eigenschaften ein- oder ausblenden und Vorlagen nur ändern, wenn sich der Laufzeittyp von ContentControl.DataContext ändert), aber ohne mehr Details, wirklich kann nicht beurteilen. –

+0

Nun, @Ed, merke ich, es kann nicht genau WPF artig sein (ich lerne nur), aber wie gesagt, 'MStatusDisplaySelector' ist nicht trivial, und ich sehe nicht, wie ich es in XAML implementieren könnte (oder eher wird es sehr ausführlich sein). Zum Beispiel ist eine der Eigenschaften ein komplexes bitweises Muster, basierend auf dem ich ein Bild oder ein Raster von Bildern oder Text anzeigen oder es insgesamt ausblenden muss. So etwas in Code-Behind zu schreiben ist einfach, aber nicht in XAML. – Zeus

+0

Sie könnten diese Logik in einem Wertkonverter tun, denke ich. Natürlich würden Sie nicht versuchen, diese Logik in XAML zu schreiben. Jedenfalls hört es sich so an, als hättest du das gedacht. –

Antwort

1

Fügen Sie diese auf Ihrem Usercontrol-Code:

protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) 
    { 
     if (e.OldValue != null && e.NewValue != null && e.Property.ToString() == "Title") 
     { 
      System.Diagnostics.Debug.WriteLine(e.Property.ToString() + " > " + e.OldValue.ToString() + " : " + e.NewValue.ToString()); 
      /* You can call your TemplateSelector method here, or put some code here */ 
     } 
     base.OnPropertyChanged(e); 
    } 

In dieser überschriebenen Methode Sie die Property inspizieren können, die diese Methode macht immer genannt, und dementsprechend geeignete Maßnahmen ergreifen.

+0

So kann ich eine Änderung erkennen. Dies ist in der Tat der einfachste Weg. Aber die Hauptfrage ist: Was soll ich tun? Wie schubse ich meinen 'ContentPresenter', um seine Vorlage zu aktualisieren? Ich könnte wahrscheinlich die 'ContentTemplateSelector' Deklaration entfernen und 'ContentTemplate' aus dem Code in diesem Handler zuweisen ... Aber das sieht mir noch mehr un-WPF ... – Zeus

+0

@Zeus Es ist unklar, ob man die Vorlage aktualisieren soll. Jedes Mal, wenn sich die an "Inhalt" gebundene Eigenschaft ändert, wird "Bindung" den "Inhalt" aktualisieren, was wiederum den "TemplateSelector" aufrufen wird. So können Sie die 'ViewModel: bound-Eigenschaft 'in der' OnPropertyChanged'-Methode ändern, die wiederum' Content' aktualisiert. – AnjumSKhan

+0

Aber das bindende Ziel ist das 'UserControl' selbst. Mit anderen Worten, effektiv ".Content = this" (Ich habe keinen "Name" in meinem ursprünglichen Code oben zugewiesen). Wenn ich diese Zuweisung in "OnPropertyChanged" erzwinge, wird es nichts tun, weil das Objekt selbst nicht geändert wurde. Nur einige seiner Eigenschaften haben es getan. – Zeus