Domanda

che sto cercando di fare la mia applicazione più personalizzabile, consentendo agli utenti di scegliere un colore da una finestra di dialogo Selettore colore, e quindi modificando lo stile dell'applicazione in tempo reale (con DynamicResource)

Come faccio a cambiare in risorse specifiche che risiedono nella app.xaml?


Ho provato qualcosa di simile, ma senza fortuna (solo una prova):

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));

Questo un estratto del file app.xaml:

<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>

Qual è il modo migliore per consentire questa forma di personalizzazione (fondamentalmente solo cambiando alcuni colori) per un'applicazione?


[Aggiornamento]

Ho appena trovato questa risposta da una domanda precedente che è stato chiesto, e ho cercato ma io sono sempre lo stesso InvalidOperationException eccezione Petoj citato nei commenti per la risposta data. Ecco il codice di esempio dalla risposta:

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;
È stato utile?

Soluzione

Sembra che si sta cercando di fare una sorta di scuoiatura?

Mi consiglia di definire le risorse in un dizionario risorse contenute in un file separato. Poi nel codice (App.cs per caricare un default, poi altrove per cambiare) è possibile caricare le risorse come:

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

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

Si potrebbe anche definire il dizionario risorse predefinito in App.xaml e scaricare nel codice bene.

Utilizzare i MergedDictionaries oggetto per cambiare il dizionario che si sta utilizzando in fase di esecuzione. Funziona come un fascino per la modifica di un intera interfaccia rapidamente.

Altri suggerimenti

Modifica risorse ampia applicazione in fase di esecuzione è come:

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

A proposito del InvalidOperationException, credo WallStreet programmatore è giusto. Forse non si dovrebbe cercare di modificare un pennello esistente, ma invece di creare un nuovo pennello in codice con tutte le gradientstops si ha bisogno, e quindi assegnare questo nuovo pennello in risorse dell'applicazione.

Un altro approccio su come cambiare il colore di alcuni GradientStops è quello di definire quei colori come riferimenti DynamicResource a un'applicazione in tutto SolidColorBrushes come:

<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>

e quindi utilizzare

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

HTH

Utilizzare il metodo Clone() di fare una copia completa del pennello (o qualsiasi altro oggetto Freezable come Storyboard) e poi usarlo:

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

@WallstreetProgrammer è giusto - tutte le risorse a livello di applicazione sono congelate per default

.

Ecco perché è necessario per clonare l'oggetto prima.

È possibile ottenere un'eccezione perché si sta cercando di modificare un oggetto ghiacciato. Tutte le risorse a livello di applicazione sono congelati automaticamente se sono freezable e LinearGradientBrush è. Se si aggiunge che a livello finestra come livello inferiore che funzionerà.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top