Обновление стилей WPF во время выполнения
-
21-09-2019 - |
Вопрос
Я хотел бы динамически обновлять стиль окна по умолчанию во время выполнения, чтобы я мог динамически изменять FontSize и FontFamily во время выполнения.Я обнаружил, что стили в вашем словаре ресурсов запечатаны во время выполнения и не могут быть изменены, поэтому я использовал следующий метод обновления стиля:
<Style TargetType="{x:Type Window}">
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="FontSize" Value="12pt"/>
</Style>
Со следующим кодом:
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;
}
У этого подхода есть несколько проблем, и у меня есть несколько вопросов относительно того, почему дела обстоят именно так, как есть.
- Почему стили запечатываются во время выполнения и есть ли способ сделать их незапечатанными?
- Когда я повторно добавляю новый стиль, почему он не поддерживается всеми моими окнами?Почему мне нужно вручную применять его к каждому окну?
- Есть ли способ лучше?
Решение
Я бы, вероятно, решил эту проблему с помощью «службы настроек», которая предоставляет свойства для различных настроек и запускает INPC, как и при обычной привязке.Далее я бы изменил этот стиль на что-то вроде:
<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>
Если ваша «служба настроек» определена как статический ресурс:
<services:SettingsService x:Key="SettingsService"/>
Затем в каждом окне убедитесь, что стиль установлен как DynamicResource:
<Window Style="{DynamicResource MyWindowStyle}" .... >
Часто возникает много недопониманий относительно различий между статическими и динамическими ресурсами, но основное различие заключается в том, что статический — это «однократная» настройка, тогда как динамический обновит настройки при изменении ресурса.
Теперь, если вы установите эти свойства в своей «службе настроек», они запустят INPC, который обновит стиль, который будет выбран DynamicResource, и соответствующим образом изменит свойства окна.
Кажется, что это большая работа, но это дает вам некоторую гибкость, и вся «тяжелая работа» выполняется исключительно с использованием привязок.Мы используем аналогичную технику в проекте, над которым я сейчас работаю, поэтому, когда пользователь выбирает цвет заливки/обводки, различные инструменты на панели инструментов обновляются, чтобы отразить новые значения.