Estilos de atualização do WPF no tempo de execução
-
21-09-2019 - |
Pergunta
Eu gostaria de atualizar o estilo de janela padrão dinamicamente em tempo de execução para que eu possa alterar o FontSize e o Fontfamily dinamicamente em tempo de execução. Descobri que os estilos no seu dicionário de recursos são selados em tempo de execução e não podem ser alterados, então usei o seguinte método para atualizar o estilo:
<Style TargetType="{x:Type Window}">
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="FontSize" Value="12pt"/>
</Style>
Com o seguinte código:
Style newStyle = (Make a copy of the old style but with the FontSize and FontFamily changed)
// Remove and re-add the style to the ResourceDictionary.
this.Resources.Remove(typeof(Window));
this.Resources.Add(typeof(Window), newStyle);
// The style does not update unless you set it on each window.
foreach (Window window in Application.Current.Windows)
{
window.Style = newStyle;
}
Existem vários problemas com essa abordagem e tenho algumas perguntas sobre por que as coisas são do jeito que são.
- Por que os estilos são selados em tempo de execução e existe uma maneira de torná -los não lacrados?
- Quando eu adicionei o novo estilo, por que isso não é capturado por todas as minhas janelas? Por que eu tenho que ir e aplicá -lo manualmente em todas as janelas?
- Existe uma maneira melhor?
Solução
Eu provavelmente resolveria isso com um "serviço de configurações" que expõe propriedades para as várias configurações e dispara a INPC como faria com a ligação normal. Em seguida, eu mudaria esse estilo para ser algo como:
<Style x:Key="MyWindowStyle">
<Setter Property="FontFamily" Value="{Binding Path=FontFamily, Source={StaticResource SettingsService}, FallbackValue=Arial}"/>
<Setter Property="FontSize" Value="{Binding Path=FontSize, Source={StaticResource SettingsService}, FallbackValue=12}"/>
</Style>
Com o seu "Serviço de Configurações" definido como um recurso estático:
<services:SettingsService x:Key="SettingsService"/>
Em cada janela, verifique se o estilo está definido como um DynamicResource:
<Window Style="{DynamicResource MyWindowStyle}" .... >
Muitas vezes, há muito mal -entendidos em torno das diferenças entre recursos estáticos e dinâmicos, mas a diferença básica é estática é uma configuração "única", enquanto a dinâmica atualiza as configurações se o recurso for alterado.
Agora, se você definir essas propriedades no seu "Serviço de Configurações", eles demitirão a INPC, que atualizarão o estilo, que o DynamicResource aceitará e alterará as propriedades da janela de acordo.
Parece muito trabalho, mas oferece uma boa flexibilidade, e todo o "levantamento pesado" é feito puramente usando ligações. Utilizamos uma técnica semelhante em um projeto em que estou trabalhando no momento; portanto, quando um usuário escolhe uma cor de preenchimento/curso, as várias ferramentas na atualização da barra de ferramentas para refletir os novos valores.