20 Stimmen

Explizit aktualisieren DataTemplate von einem DataTemplateSelector?

Ich habe einen ContentControl.DataTemplateSelector nach meinem Wunsch erstellt.
Ich möchte, dass je nach Befehl oder was auch immer, der ContentControl aufgerufen wird, um das Template erneut aus dem Selector auszuwählen, entweder per XAML oder Code.

Danke

21voto

Jens Punkte 24565

Spät zur Party, ich weiß. =)

Als ich mit diesem Problem konfrontiert wurde, fand ich es am einfachsten, explizit einen neuen TemplateSelector wie folgt festzulegen

MyContentControl.ContentTemplateSelector =
     new MyDataTemplateSelector();

0 Stimmen

+1 es ist nie zu spät! im Gegensatz zu anderen Beiträgen, die deprimierend sind, weil sie dir sagen, dass es keinen Weg gibt, das zu tun, was du willst! Deine Lösung funktioniert und hat mir eine großartige Idee gegeben, die ich in Kürze posten werde, wenn ich heute Zeit habe.

0 Stimmen

Was ich tatsächlich gemacht habe, ist, jeden Presenter zu speichern, der SelectTemplate aufruft (als eine schwache Referenz) in meinem DataTemplateSelector und eine statische Methode bereitzustellen, um all diese zu aktualisieren.

0 Stimmen

Was passiert, wenn Sie das Eigenschaftsänderungsereignis auf der gebundenen Eigenschaft auslösen (wenn Sie an Ihre eigene Klasse binden)?

15voto

fraggy Punkte 141

Ich glaube, ich bin sogar noch später zur Party gekommen, aber für eine andere Idee, die jemandem helfen könnte...

Sie könnten auch versuchen, einen ValueConverter für die ContentTemplate-Eigenschaft des ContentControls anstelle eines DataTemplateSelector zu verwenden.

Erstellen Sie einfach eine Eigenschaft in Ihrem DataContext, an die Sie binden können, wie z.B. ScreenNumber. Geben Sie dann im ValueConverter das DataTemplate zurück, das mit der ScreenNumber verknüpft ist.

Beispiel ValueConverter:

public class ValueDataTemplateConverter : IValueConverter
{
    public DataTemplate TemplateA { get; set; }
    public DataTemplate TemplateB { get; set; }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is ValueType valueType)
            switch (valueType)
            {
                case ValueType.TypeA:
                    return TemplateA;
                case ValueType.TypeB:
                    return TemplateB;
             }

        return null;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Beispiel XAML-Ressource:

1 Stimmen

Vielen Dank für das Aktualisieren dieser Jahre später. Ich hätte nicht daran gedacht, einen Konverter zu verwenden, und diese Lösung erfordert keinen Code dahinter. Sehr schön.

11voto

itowlson Punkte 72130

Ich kenne keine (nicht kludgy) Möglichkeit, dies zu tun: Der DataTemplateSelector wird aufgerufen, wenn WPF das Template auswählen muss, und das ist eine einmalige Entscheidung, soweit WPF betroffen ist. (Sie können es durch einen Kludge machen, indem Sie WPF glauben lassen, dass sich der Inhalt geändert hat, z. B. indem Sie den Inhalt auf null setzen und dann wieder zurück -- ich denke, das würde funktionieren, aber ich habe es nicht getestet -- aber das ist ziemlich hässlich!) Wenn es einen guten Weg gibt, dies zu tun, würde ich auch gerne wissen!

Es gibt jedoch eine alternative Möglichkeit, wie der Inhalt angezeigt wird, die auf Datenänderungen reagiert, und das sind Trigger. Sie können DataTriggers in Ihrer DataTemplate.Triggers-Sammlung verwenden, um Elemente abhängig von den Inhaltsdaten anzuzeigen und auszublenden. Um die gesamte Anzeige zu ändern, könnten Sie z. B. zwei Darstellungen in einem Raster einrichten und Trigger verwenden, um festzulegen, welche sichtbar ist. Sie könnten sogar Ihr Daten-Template zu einem ContentControl machen und einen Trigger verwenden, um das ContentTemplate zu ändern. Natürlich hängt dies davon ab, dass die Kriterien für die Änderung des Templates bindbare Eigenschaften sind, was nicht immer der Fall sein kann.

Hier finden Sie eine kurze Diskussion über Selektoren vs. Trigger, wenn auch in einem etwas anderen Kontext.

1 Stimmen

Ich habe Probleme bei der Verwendung mit DataTrigger, bitte schau dir das an: stackoverflow.com/questions/2090148/…

6voto

Goldorak84 Punkte 3490

Ähnlich wie in Jens Antwort, anstatt eine neue Instanz zu erstellen, können Sie die vorhandene Instanz des DataTemplateSelector verwenden.

var currentSelector = MyContentControl.ContentTemplateSelector;     
MyContentControl.ContentTemplateSelector = null;
MyContentControl.ContentTemplateSelector = currentSelector;

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