Ich würde meinem Benutzer gern die Möglichkeit geben einige Farben in der GUI zu ändern. Ich dachte dabei dass es mit Dynamic Resouces am einfachsten geht, habe aber momentan noch Probleme. Hier mein Aufbau:
Ich habe ein ResourceDictionary für Farben welches in der Datei Colors.xaml enthalten ist. In diesem ResourceDictionary habe ich den SolidColorBrush 'CaptionLabelBrush' definiert.
In einem weiteren ResourceDictionary welches in der Datei Controls.xaml enthalten ist habe ich ein Style für Labels namens 'CaptionLabel' definiert welches als Background den zuvor genannten SolidColorBrush als DynamicResource verwendet. Damit das geht wurde im zweiten ResourceDictionary das erste als MergedDictionary angegeben.
In meiner inzwischen recht komplexen Oberfläche wird nun an vielen unterschiedlichen Stellen das Controls-ResourceDictionary als MergedDictionary verwendet. Dies wäre zwar zur Laufzeit eigentlich nicht nötig da es ja vom Window nach unten and UserControls durchgereicht wird, allerdings sieht sonst im Cider die Vorschau gänzlich falsch aus.
Die verwendeten UserControls aber auch das Controls-ResourceDictionary stammen aus separaten Projekten bzw. dlls.
Das einbinden der MergedDictionaries erfolgt mit Hilfe einer eigenen SharedResourceDictionary Klasse welche sicherstellt das ein und das selbe ResourceDictionary nicht mehrmals von unterschiedlichen UserControls neu geladen und instanziert wird. Es sollte folglich in der ganzen Anwendung nur eine Instanz des Controls-ResourceDictionary geben welches von allen Windows/UserControls genutzt wird.
Nun war mein Ziel das der Benutzer die Farbe die im CaptionLabelBrush definiert ist zur Laufzeit ändern kann damit im Anschluß alle CaptionLabels die neue Farbe erhalten. Das seltsame ist dass das auch funktioniert, aber nicht überall gleich: Je nachdem wie und wo ich in meinem Code das ResourceDictionary zu erreichen versuche wird die Änderung sichtbar oder scheinbar ignoriert. Folgende Möglichkeiten konnte ich ausfindig machen:
SharedResourceDictionary controlsResDict = new SharedResourceDictionary();
controlsResDict.Source = new Uri("pack://application:,,,/Common.Themes;component/Controls.xaml");
if (controlsResDict Resources.Contains("CaptionLabelBrush"))
{
controlsResDict ["CaptionLabelBrush"] = theNewBrush;
}
if (this.Resources.Contains("CaptionLabelBrush"))
{
this.Resources["CaptionLabelBrush"] = theNewBrush;
}
if (Application.Current.Resources.Contains("CaptionLabelBrush"))
{
Application.Current.Resources["CaptionLabelBrush"] = theNewBrush;
}
Leider hängt es scheinbar davon ab wo ich die Änderung durchführe um damit erfolgreich zu sein (App.xaml.cs oder ViewModel oder auch direkt inm CodeBehind). Auch hatte ich teilweise das Phänomen das manche UserControls die neue Frabe erhielten und andere nicht, obgleich diese jeweils auf der gleichen Ebene standen jedoch aus unterschiedlichen dlls kamen.
Letztlich scheint mir nur der Weg über 'this.Resources' zuverlässig zu sein allerdings ist dieser auch am Aufwendigsten da dies direkt im CodeBehind zu geschehen hat und dies ein ernsthaftes Verteilungsproblem darstellt.
Hat jemand von euch eine Idee oder einen Hinweis was ich falsch mache bzw. wie man das richtig angeht?
Hat jemand von euch so ein Szenario bereits erfolgreich gelöst?
Viele Grüße
Ralf