Pergunta

Eu estou tentando fazer minha aplicação mais personalizável, permitindo aos usuários escolher uma cor a partir de um diálogo Color Picker, em seguida, mudando o estilo da aplicação em tempo real (com DynamicResource)

Como faço para ir sobre na mudança de recursos específicos que residem no app.xaml?


Eu tentei algo assim, mas sem sorte (apenas um teste):

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

Este um trecho do arquivo 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 é a melhor maneira de permitir que esta forma de personalização (basicamente apenas mudando algumas cores) para uma aplicação?


[Update]

Eu só descobri este resposta de uma pergunta anterior que foi perguntado, e tentou -lo, mas eu estou recebendo o mesmo InvalidOperationException exceção Petoj mencionado nos comentários para a resposta dada. Aqui está o código de exemplo da resposta:

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

Solução

Parece que você está tentando fazer algum tipo de esfola?

Eu recomendo definindo os recursos em um dicionário de recursos contidos em um arquivo separado. Em seguida, no código (App.cs para carregar um padrão, em seguida, em outro lugar para a mudança), você pode carregar os recursos assim:

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

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

Você também pode definir o dicionário de recurso padrão em App.xaml e descarregá-lo em código apenas multa.

Use as MergedDictionaries opor-se a alterar o dicionário que você está usando em tempo de execução. Funciona como um encanto para mudar uma interface inteira rapidamente.

Outras dicas

Alterar recursos ampla aplicação em tempo de execução é semelhante:

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

Sobre o InvalidOperationException, eu acho WallStreet programador é certo. Talvez você não deve tentar modificar um pincel existente, mas sim criar um novo pincel em código com todos os gradientstops que você precisa, e depois atribuir esse novo pincel em recursos do aplicativo.

Outra abordagem sobre como alterar a cor de algumas GradientStops é definir essas cores como referências DynamicResource da aplicação SolidColorBrushes largos 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>

e, em seguida, usar

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

HTH

Use o método Clone() para fazer uma cópia profunda do pincel (ou qualquer outro objeto freezable como Storyboard) e, em seguida, usá-lo:

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

@WallstreetProgrammer é certo -. Todos os recursos nível de aplicativo são congelados por padrão

É por isso que você precisa para clonar o objeto em primeiro lugar.

Você recebe uma exceção porque você está tentando modificar um objeto congelado. Todos os recursos de nível de aplicativo são automaticamente congelados se estiverem freezable e LinearGradientBrush é. Se você adicioná-lo em um nível inferior, como nível de janela que vai funcionar.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top