Laden...

Kann man für Dark/Light Mode ControlTemplate und Style in verschiedene ResourceDictionaries legen?

Erstellt von ByteDevil vor 3 Jahren Letzter Beitrag vor 3 Jahren 813 Views
ByteDevil Themenstarter:in
132 Beiträge seit 2013
vor 3 Jahren
Kann man für Dark/Light Mode ControlTemplate und Style in verschiedene ResourceDictionaries legen?

Hi,

folgendes Szenario: In einer größeren Solution die aus vielen Projekten besteht (C++ code und UI, Windows Forms UI und nun auch WPF) soll es nun möglich sein, bei den neuen Programmteilen welche in WPF umgesetzt sind, zur Laufzeit zwischen einem Dark- und einem Light-Mode umzuschalten. Nun überlege ich gerade wie man das Ganze strukturieren kann, damit es später möglichst einfach wird die controls zu stylen und zu nutzen...hier kommen Standard WPF-Controls zum einsatz, sowie UserControls und CustomControls.

Meine Idee war:

Ich definiere von jedem Control zwei Styles (Light und Dark) und (wenn nötig) ein ControlTemplate, da das Template ja immer gleich sein soll. Sowohl das Template als auch jeder Style soll in ein eigenes ResourceDictionary... Das mit den Templates wird von jedem der Theme-ResourceDictionaries eingebunden und eines der beiden Themes wird dann von dem Window eingebunden. So wirken sich Änderungen an einem Template auf beide Themes aus.

Versuche in nun folgendes:

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:TestProject">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="ControlTemplates.xaml"/>
    </ResourceDictionary.MergedDictionaries>

    <Style TargetType="{x:Type local:MyButton}">
        <Setter Property="Background" Value="#494949"/>
        <Setter Property="Foreground" Value="#DEDEDE"/>
        <Setter Property="Template" Value="{DynamicResource MyButtonTemplate}"/>
    </Style>
</ResourceDictionary>

(ControlTemplates.xaml enthält erstmal nur ein ControlTemplate mit dem Key "MyButtonTemplate" mit dem TargetType "MyButton". MyButton ist ein CustomControl welches von Button erbt. Musste einige zusätzliche Properties einbauen)

und binde dieses ResourceDictionary nun in meine Window.Resources ein, bekomme ich folgende Exception direkt beim Start:

Fehlermeldung:
System.Windows.Markup.XamlParseException: "Zeilennummer "17" und Zeilenposition "48" von "Beim Festlegen der Eigenschaft "System.Windows.Setter.Value" wurde eine Ausnahme ausgelöst."."

Innere Ausnahme:
ArgumentException: Bei dem Ausdruckstyp handelt es sich nicht um einen gültigen Style-Wert.

Das Problem scheint beim Setter des Templates zu liegen. Kommentiere ich das aus, kracht es nicht mehr...natürlich ist dann von dem Control nichts zu sehen, weil kein Template da ist.

Compiliert prima und IntelliSense bzw. Resharper meckert auch nirgends.
Packe ich das Template direkt in den Setter und definiere es somit in dem Style, klappt alles ganz prima. Auch das umschalten zur Laufzeit. Dann habe ich das Template aber in jedem Theme einmal drin stehen und das obwohl es immer identisch ist. Das heißt ich muss immer beide anpassen wenn ich was ändere und es bläht die beiden Themes sehr auf. Das wollte ich so nur machen, falls es tatsächlich mal den Fall gibt, dass das Template sich in beiden Themes unterscheiden soll.

Ist das was ich da vor habe überhaupt möglich? Wenn ja was mache ich falsch?

Habe diesen oder einen ähnlichen Ansatz noch nirgends im Netz entdeckt.

W
955 Beiträge seit 2010
vor 3 Jahren

Verwende doch einfach Mahapps.Metro

ByteDevil Themenstarter:in
132 Beiträge seit 2013
vor 3 Jahren

@witte Hi und danke für die Antwort 😃 Mhhh 3rd Party-Libs würde ich da gern wenn möglich vermeiden. Das muss doch mit WPF-Boardmitteln möglich sein, oder? Aber ich behalte den Tipp im Hinterkopf.

ByteDevil Themenstarter:in
132 Beiträge seit 2013
vor 3 Jahren

Update: Entschuldigt bitte...es funktioniert ganz genauso wie ich es beschrieben habe. Es war ein Fehler im Template selbst, der sich da reingeschummelt hat. Also kann man so machen wie ich, falls das jemandem weiterhilft. Danke 😃