Frage

Ich versuche, meine Anwendung anpassbarer zu gestalten, indem ich Benutzern erlaube, eine Farbe aus einem Farbauswahldialog auszuwählen und dann den Stil der Anwendung in Echtzeit zu ändern (mit DynamicResource)

Wie gehe ich vor, wenn ich bestimmte Ressourcen ändere, die sich in der befinden? app.xaml ?


Ich habe so etwas versucht, aber kein Glück (nur ein Test):

var colorDialog = new CustomControls.ColorPickerDialog();
var dResult = colorDialog.ShowDialog();
var x = Application.Current.Resources.Values.OfType<LinearGradientBrush>().First();
x = new LinearGradientBrush();
x.GradientStops.Add(new GradientStop(colorDialog.SelectedColor,1));

Dies ist ein Auszug aus dem app.xaml Datei:

<Application.Resources>
        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0" x:Key="HeaderBackground">
            <GradientStop Color="#82cb02" Offset="1"/>
            <GradientStop Color="#82cb01" Offset="0.2"/>
            <GradientStop Color="#629a01" Offset="0.5"/>
        </LinearGradientBrush>

Was ist der beste Weg, diese Form der Anpassbarkeit (im Grunde nur das Ändern einiger Farben) für eine Anwendung zu ermöglichen?


[Aktualisieren]

Ich habe gerade gefunden diese Antwort aus einer früheren Frage, die gestellt wurde, und habe es versucht, aber ich bekomme das Gleiche InvalidOperationException Ausnahme, die Petoj in den Kommentaren für die gegebene Antwort erwähnt hat.Hier ist der Beispielcode aus der Antwort:

Xaml:

<LinearGradientBrush x:Key="MainBrush" StartPoint="0, 0.5" EndPoint="1, 0.5" >
    <GradientBrush.GradientStops>
        <GradientStop Color="Blue" Offset="0" />
        <GradientStop Color="Black" Offset="1" />
    </GradientBrush.GradientStops>
</LinearGradientBrush>

C#:

LinearGradientBrush myBrush = FindResource("MainBrush") as LinearGradientBrush;
myBrush.GradientStops[0].Color = Colors.Red;
War es hilfreich?

Lösung

Es sieht aus wie Sie versuchen, irgendeine Art von Häuten zu tun?

Ich würde empfehlen, die Ressourcen in einem Ressourcenverzeichnis in einer separaten Datei enthalten definieren. Dann im Code (App.cs einen Standard zu laden, dann an anderer Stelle zu ändern), um die Ressourcen so laden kann:

//using System.Windows
ResourceDictionary dict = new ResourceDictionary();
dict.Source = new Uri("MyResourceDictionary.xaml", UriKind.Relative);

Application.Current.Resources.MergedDictionaries.Add(dict);

Sie können auch den Standard-Ressource-Wörterbuch in App.xaml definieren und in Code entladen gut.

Mit dem MergedDictionaries Objekt das Wörterbuch zu ändern, die Sie zur Laufzeit verwenden. Funktioniert wie ein Zauber schnell eine ganze Schnittstelle zu ändern.

Andere Tipps

Das Ändern anwendungsweiter Ressourcen zur Laufzeit sieht folgendermaßen aus:

Application.Current.Resources("MainBackgroundBrush") = Brsh

Was die InvalidOperationException betrifft, denke ich, dass WallStreet Programmer Recht hat.Vielleicht sollten Sie nicht versuchen, einen vorhandenen Pinsel zu ändern, sondern stattdessen im Code einen neuen Pinsel mit allen benötigten Verlaufsstopps erstellen und diesen neuen Pinsel dann in den Anwendungsressourcen zuweisen.

Ein anderer Ansatz zum Ändern der Farbe einiger GradientStops besteht darin, diese Farben als DynamicResource-Referenzen auf anwendungsweite SolidColorBrushes zu definieren, wie zum Beispiel:

<LinearGradientBrush x:Key="MainBrush" StartPoint="0, 0.5" EndPoint="1, 0.5" >
<GradientBrush.GradientStops>
    <GradientStop Color="{DynamicResource FirstColor}" Offset="0" />
    <GradientStop Color="{DynamicResource SecondColor}" Offset="1" />
</GradientBrush.GradientStops>

und dann verwenden

Application.Current.Resources["FirstColor"] = NewFirstColorBrsh
Application.Current.Resources["SecondColor"] = NewSecondColorBrsh

HTH

Mit der Clone() Methode eine tiefe Kopie der Bürste machen (oder jede anderen freezable Objekte wie Storyboard) und dann verwenden:

LinearGradientBrush myBrush = FindResource("MainBrush") as LinearGradientBrush;
myBrush = myBrush.Clone();
myBrush.GradientStops[0].Color = Colors.Red;

@WallstreetProgrammer ist richtig - alle Anwendungsebene Ressourcen standardmäßig eingefroren werden

.

Das ist, warum Sie müssen zuerst das Objekt klonen.

Sie erhalten eine Ausnahme, weil Sie ein gefrorenes Objekt zu ändern versuchen. Alle Anwendungsebene Ressourcen werden automatisch eingefroren, wenn sie freezable sind und LinearGradientBrush ist. Wenn Sie es auf einem niedrigeren Niveau wie Fensterebene hinzufügen wird es funktionieren.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top