Стиль Windows из ResourceDictionary не применяется - программирование
Подтвердить что ты не робот

Стиль 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 остается белым.

4b9b3361

Ответ 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>