Стиль Windows из ResourceDictionary не применяется
Поскольку у меня есть несколько Window
в моем приложении, я ищу решение, которое не требует от меня установить binding
для каждого Window
.
Я создал a ResourceDictionary
, у которого есть style
для Background Window:
<Style TargetType="{x:Type Window}">
<Setter Property="Background" Value="AliceBlue"/>
</Style>
В моем XAML
я установил ResourceDictionary
:
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Templates.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
Нет ошибки, но цвет Window
остается белым.
Ответы
Ответ 1
Добавьте новую кисть в словарь ресурсов
<SolidColorBrush x:Key="WindowBackground" Color="AliceBlue" />
и в вашем окне WPF просто установите требуемый ресурс в свойство фона фона
<Window x:Class="GDD.Presentation.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="300" Width="300"
Background="{StaticResource WindowBackground}">
Ответ 2
Это, по-видимому, вызвано комбинацией порядка, в котором WPF загружает/обрабатывает стили из вложенных ResourceDictionary
и спецификаций класса Window
.
Предположим, что MainWindow
определяется как ваш пост. Теперь поставьте следующее в Templates.xaml
:
<Style TargetType="{x:Type Window}">
<Setter Property="Background" Value="Red"/>
</Style>
<Style TargetType="{x:Type Window}" x:Key="myStyle">
<Setter Property="Background" Value="Green"/>
</Style>
Если MainWindow
не имеет определенного стиля, вы увидите, что в дизайнере он появляется с красным фоном. Дизайнер разбирает весь Xaml и загружает словарь ресурсов, а затем рисует результаты. Стиль читается перед окном, и поэтому применяется красный фон.
При запуске приложения окно создается до применения ResourceDictionary
. Он ищет стиль по умолчанию (стиль с x:Key="{x:Type Window}"
) перед обработкой вложенного ResourceDictionary
и ничего не находит. Поэтому во время выполнения появляется окно с цветом по умолчанию. (Это поведение описано в комментариях выше.) Помните, что стиль с x:Key="{x:Type Window}"
имеет значение по умолчанию, соответствующее стилю Windows.
Это подтверждается, если вы явно используете myStyle
. Если вы добавите в определение Window
атрибут Style="{StaticResource myStyle}"
, вы обнаружите, что конструктор терпит неудачу, но вы также получите ошибку во время выполнения, потому что myStyle
не был создан в то время, когда Window нуждается в нем, Если вы перейдете на Style="{DynamicResource myStyle}"
, вы увидите, что он работает так, как вы надеетесь, потому что DynamicResource
будет обновляться после того, как ResourceDictionary
будет проанализирован, а стиль включен.
Итак, применяя это, вы можете устранить проблему одним способом, добавив это в свой элемент Window: Style="{DynamicResource {x:Type Window}}"
- но это неуклюже. Лучшее решение состоит в том, чтобы включить словарь ресурсов в файл app.xaml
, где он будет разбираться до того, как откроется любое окно и, таким образом, будет доступно всем:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Templates.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
Реальная проблема здесь в том, что ваш Window
на самом деле не является Window
: это класс, который происходит от Window
и на самом деле будет MainWindow
, Window2
и т.д. Это означает что автоматическая настройка стиля для Window
никогда не будет работать таким образом, и, к сожалению, всегда будет требоваться некоторый уровень ручной привязки.
Ответ 3
Это решение, которое я использовал в своем приложении. Это позволяет мне сохранять все мои стили окна и требует всего пару строк после раздела <Window.Resources>
.
Сделайте свой Style
следующим образом:
<Style x:Key="MyWindowStyle">
<Setter Property="Window.Background" Value="AliceBlue"/>
</Style>
Затем в вашем окне после </Window.Resources>
укажите следующее:
<Window.Style>
<Style BasedOn="{StaticResource MyWindowStyle}"/>
</Window.Style>