WPF Aggiornamento stili in fase di esecuzione
-
21-09-2019 - |
Domanda
Vorrei aggiornare lo stile della finestra di default in modo dinamico in fase di esecuzione in modo da poter cambiare il FontSize e FontFamily dinamicamente a runtime. Ho trovato che stili nel vostro dizionario risorse sono sigillati in fase di esecuzione e non possono essere cambiati, così ho usato il seguente metodo di aggiornamento dello stile:
<Style TargetType="{x:Type Window}">
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="FontSize" Value="12pt"/>
</Style>
Con il seguente codice:
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;
}
Ci sono diversi problemi con questo approccio e ho alcune domande sul perché le cose sono come sono.
- Perché sono stili sigillati in fase di esecuzione e c'è un modo di renderli non sigillata?
- Quando ho ri-aggiungere il nuovo stile, perché questo non è raccolto da tutte le mie finestre? Perché devo andare e applicarlo a tutte le finestre manualmente?
- C'è un modo migliore?
Soluzione
Io probabilmente affrontare questo con un "Servizio relativo alle impostazioni", che espone le proprietà per le varie impostazioni, e spara INPC come si farebbe per il normale vincolante. Next up che vorrei cambiare stile che essere qualcosa di simile:
<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>
Con il "Servizio relativo alle impostazioni" definito come una risorsa statica:
<services:SettingsService x:Key="SettingsService"/>
Quindi in ogni finestra assicurarsi che lo stile è impostato come un DynamicResource:
<Window Style="{DynamicResource MyWindowStyle}" .... >
v'è spesso un sacco di malintesi intorno alle differenze tra risorse statiche e dinamiche, ma la differenza fondamentale è statico è un "one time" impostazione, mentre Dynamic aggiornare le impostazioni se i cambiamenti di risorse.
Ora, se si imposta le proprietà nel "Servizio relativo alle impostazioni" che spareranno INPC, che aggiornerà la Style, che il DynamicResource si salire su e alterare le proprietà della finestra di conseguenza.
Sembra un sacco di lavoro, ma ti dà qualche bella la flessibilità, e tutto il "lavoro pesante" è fatto puramente utilizzando Associazioni. Usiamo una tecnica simile a un progetto su cui sto lavorando in questo momento così quando un utente sceglie un colore di riempimento / corsa i vari strumenti nella barra degli strumenti di aggiornamento per riflettere i nuovi valori.