Pregunta

Estoy tratando de hacer mi aplicación más personalizable, permitiendo a los usuarios elegir un color de un cuadro de diálogo Selector de color, y luego cambiar el estilo de la aplicación en tiempo real (con DynamicResource)

¿Cómo hago para cambiar los recursos específicos que residen en el app.xaml?


He intentado algo así, pero sin suerte (sólo una prueba):

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

Esto muestra un extracto del archivo 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>

¿Qué es la mejor manera de permitir que esta forma de personalización (básicamente sólo cambiar algunos colores) para una aplicación?


[Actualización]

respuesta de una pregunta anterior que se hizo, y traté pero estoy consiguiendo el mismo excepción InvalidOperationException Petoj menciona en los comentarios de la respuesta dada. Aquí está el código de ejemplo de la respuesta:

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;
¿Fue útil?

Solución

Parece que estamos tratando de hacer algún tipo de desollar?

Me gustaría recomendar la definición de los recursos en un diccionario de recursos contenidos en un archivo separado. A continuación, en el código (App.cs para cargar un defecto, entonces en otro lugar a cambios) se pueden cargar los recursos de modo que:

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

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

También se puede definir el diccionario de recursos predeterminado en App.xaml y descargarlo en el código muy bien.

Utilice los MergedDictionaries objeto para cambiar el diccionario que está usando en tiempo de ejecución. Funciona como un encanto para cambiar toda una interfaz rápidamente.

Otros consejos

Cambio de aplicación amplios recursos en tiempo de ejecución es como:

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

Sobre el InvalidOperationException, supongo WallStreet programador es correcto. Tal vez usted no debe tratar de modificar un cepillo existente, pero en lugar de crear un nuevo pincel en código con todas las gradientstops que necesita, y luego asignar este nuevo cepillo de recursos de la aplicación.

Otro enfoque sobre cómo cambiar el color de algunos GradientStops es definir esos colores como referencias DynamicResource a la extensa aplicación SolidColorBrushes como:

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

y luego usar

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

HTH

Utilice el método Clone() para hacer una copia profunda del cepillo (o cualquier otro objeto congelable como Storyboard) y luego usarlo:

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

@WallstreetProgrammer es correcto - todos los recursos a nivel de aplicación se congelan de forma predeterminada

.

Es por eso que necesita clonar el objeto en primer lugar.

Se obtiene una excepción ya que están tratando de modificar un objeto congelado. Todos los recursos a nivel de aplicación se congelan de forma automática si son congelable y LinearGradientBrush es. Si se agrega en un nivel ventana como nivel inferior que va a funcionar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top