Ist es möglich, einen Standardstil für ein generisches Basissteuerelement in WPF bereitzustellen?
Angenommen, ich habe die folgenden Basisklassen:
%Vor%Dann nehme ich an, ich habe zwei Klassen, die von diesen Basisklassen erben:
%Vor%Jetzt möchte ich einen Standardstil für das Basissteuerelement bereitstellen, das alle meine abgeleiteten Steuerelemente verwenden:
%Vor%Wenn ich jedoch mein TestView-Steuerelement verwende, wird das Template-Markup nicht angewendet (und somit kann jeder Inhalt, den ich im XAML meines TestView-Steuerelements definiere, nicht im visuellen / logischen Baum enthalten sein).
Ich versuche im Grunde, meine Basis-View / View-Model-Klassen zu verwenden und ein konsistentes Look-and-Feel anzuwenden. Dies funktioniert natürlich in den nicht-generischen Basissichtfällen. Allerdings benötige ich die typsichere Verbindung zwischen Ansicht und Ansichtsmodell, so dass ich Methoden auf dem Ansichtsmodell von allem aufrufen kann, das sich auf die Ansicht bezieht (von der ich weiß, dass sie "nicht gut sitzt" mit der Art, wie einige Leute MVVM implementiert haben).
Ich habe eine ziemlich einfache Lösung gefunden, die eine benutzerdefinierte TypeExtension
enthält.
1 - Setzen Sie den DefaultStyleKey auf den standardmäßigen generischen Typ , wie in der Antwort von CodeNaked erwähnt :
%Vor% 2 - Erstellen Sie die folgende Klasse, die von System.Windows.Markup.TypeExtension
3 - Aktualisieren Sie den TargetType des Stils so, dass er auf die neue Erweiterung local:Type
anstelle der üblichen Erweiterung x:Type
Das ist es ..
Es gibt jedoch eine Einschränkung: VS löst einen Kompilierungsfehler aus, wenn Sie versuchen, eine der in der Ansicht & lt; T & gt; Klasse. Sie können also keine einfache Syntax wie {TemplateBinding ViewTProperty}
...
Kurze Antwort: nein
Lange Antwort:
In Ihrem Code dahinter geben Sie einen DefaultStyleKey von typeof(View<T>)
an, wobei T in einen tatsächlichen Typ aufgelöst wird. Im XAML machen Sie effektiv typeof(Value<>)
, wobei T immer noch "undefiniert" ist.
Sie können Ihren DefaultStyleKey auf:
setzen %Vor% Dies wird den Style korrekt finden, aber wird zu einer Ausnahme führen (da TestView
nicht auf View<>
fallen kann).
Am besten definierst du deinen Basis-Style wie du, aber gib ihm ein x: Key wie "ViewBaseStyle". Erstellen Sie dann für jeden Ableitetyp, der BasedOn ViewBaseStyle ist, einen Style.
Wie ich es gemacht habe, habe ich eine Basisklasse ohne Generika gemacht und das Template erstellt. Dann vererbe ich die Basisklasse mit einer generischen Klasse (nicht templated), die verwendet werden kann, um Ihre Klassenvariationen zu machen (auch nicht templated). In der Tat würde alles, was die Basisklasse (ohne Generika) erbt, die gleiche Vorlage haben.
Zum Beispiel
%Vor% ViewBase
, View<T>
und DecimalView
haben jetzt alle denselben Standardstil. Darüber hinaus können Sie für jede Klassenvariation einen individuellen Stil basierend auf dem ursprünglichen Stil angeben ( ViewBase
), nicht jedoch für die generische Klasse.
Es ist erwähnenswert, dass der beste Weg, sich an die Eigenschaften der obersten Klassenklasse zu binden, die Syntax {Binding Path, RelativeSource={RelativeSource AncestorType={x:Type ViewBase}}}
gegenüber {TemplateBinding Path}
ist. Letztere sowie {Binding Path, RelativeSource={RelativeSource TemplatedParent}}
sind nur auf Eigenschaften anwendbar, die ViewBase
gehören.
Tags und Links wpf