Question

Je suis en train de faire ma demande plus personnalisable en permettant aux utilisateurs de choisir une couleur d'un dialogue Sélecteur de couleurs, puis changer le style de l'application en temps réel (avec DynamicResource)

Comment puis-je aller au sujet de l'évolution des ressources spécifiques qui résident dans le app.xaml?


Je l'ai essayé quelque chose comme ça, mais pas de chance (juste un 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));

un extrait du fichier 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>

Quelle est la meilleure façon de permettre à cette forme de customizability (fondamentalement juste changer certaines couleurs) à une application?


[Mise à jour]

Je viens de découvrir cette réponse d'une question précédente qui a été posée, et essayé mais je reçois le même InvalidOperationException exception Petoj mentionné dans les commentaires pour la réponse donnée. Voici l'exemple de code de la réponse:

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;
Était-ce utile?

La solution

On dirait que vous essayez de faire une sorte de écorcher?

Je vous recommande de définir les ressources dans un dictionnaire des ressources contenues dans un fichier séparé. Ensuite, dans le code (App.cs pour charger un défaut, puis ailleurs à changer), vous pouvez charger les ressources comme ceci:

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

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

Vous pouvez également définir le dictionnaire de ressources par défaut dans App.xaml et décharger dans le code très bien.

Utilisez les MergedDictionaries objet pour modifier le dictionnaire que vous utilisez lors de l'exécution. Fonctionne comme un charme pour changer rapidement une interface entière.

Autres conseils

Modification de l'application de larges ressources d'exécution est comme:

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

A propos de la InvalidOperationException, je suppose que WallStreet programmeur est juste. Peut-être que vous ne devriez pas essayer de modifier une brosse existante, mais au lieu de créer une nouvelle brosse dans le code avec tous les GradientStops dont vous avez besoin, puis attribuez-lui cette nouvelle brosse dans les ressources d'application.

Une autre approche sur le changement de couleur de certains GradientStops est de définir les couleurs comme références DynamicResource à une large application SolidColorBrushes comme:

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

et puis utilisez

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

HTH

Utilisez la méthode Clone() pour faire une copie complète de la brosse (ou tout autre objet comme Storyboard congelable) et ensuite l'utiliser:

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

@WallstreetProgrammer est juste - toutes les ressources de niveau d'application sont gelés par défaut

.

C'est pourquoi vous devez cloner l'objet premier.

Vous obtenez une exception parce que vous essayez de modifier un objet congelé. Toutes les ressources de niveau d'application sont automatiquement bloqués si elles sont congelable et LinearGradientBrush est. Si vous ajoutez à un niveau de fenêtre comme de niveau inférieur, il fonctionnera.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top