Стиль WPF для базового окна не применяется в приложении.xaml, но находится в темах / Generic.код XAML

я нахожусь в процессе создания базового класса окна для большинства моих окон для получения. Очевидно, лучшим решением для этого был отдельный класс и стиль, который к нему применяется.

проблема в том, что <Style ../> Я не применяется, когда он находится в App.Resources. То есть, если он определен во внешнем ResourceDictionary, и слились в App.xamlресурсы, или локальный словарь и объединены или помещены вApp.Resources. The <Style ../>, однако, применяется, когда это помещено в Themes/Generic.xaml.

проблема может быть продемонстрирована без каких-либо специальных действий в базовом окне, кроме переопределения DefaultStyleKeyProperty.

ниже ThemeWindow:

public class ThemeWindow : Window
{
    static ThemeWindow()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(ThemeWindow), new FrameworkPropertyMetadata(typeof(ThemeWindow)));
    }
}

вот очень простой <Style ../> Я пытаюсь применить (это делает Window красный фон, ничего больше):

<Style TargetType="{x:Type testing:ThemeWindow}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type testing:ThemeWindow}">
                <Grid>
                    <Grid.Background>
                        <SolidColorBrush Color="Red"/>
                    </Grid.Background>
                    <AdornerDecorator>
                        <ContentPresenter />
                    </AdornerDecorator>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

на MainWindow использует ThemeWindow, это просто следующий XAML:

<testing:ThemeWindow x:Class="Testing.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:testing="clr-namespace:Testing"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Button Content="Button" HorizontalAlignment="Left" Margin="125,83,0,0" VerticalAlignment="Top" Width="75"/>
    </Grid>
</testing:ThemeWindow>

теперь, как указано, если вы разместите это Style в своем ResourceDictionary, и включить его так:

<App.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="/Themes/ThemeWindow.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</App.Resources>

.. это не работает. Если вы встроите стиль прямо в App.Resources, он не работает.

на только ситуация я могу найти, что она работает, чтобы вызвать ResourceDictionary в XAML Generic.xaml, и поместите его в приложения.

мне интересно, почему это происходит.

моя единственная теория заключается в том, что когда WPF видит тип элемента управления, он отправлюсь в Themes, и просканировать все ResourceDictionaryS для типа, а затем вернуться к Generic.xaml и загрузить его. Это не объясняет, почему он не будет загружаться, если <Style /> доступен в объединенном ResourceDictionary хотя. Примечание что он работает, если MergedDictionary расположенный в Generic.xaml, по понятным причинам.

я прекрасно сольется с ResourceDictionary на Generic.xaml если это то, что я должен сделать. Я просто хочу разобраться в технических деталях, почему это необходимо быть таким.

скриншоты этого не работают / работают: Broken ImageWorking Image

2 ответов


у меня есть простой обходной путь, который позволит вам установить свой стиль в приложение.код XAML.

определите свой стиль в приложение.xaml вот так:

<Style x:Key="{x:Type testing:ThemeWindow}" TargetType="{x:Type testing:ThemeWindow}">

и измените ThemWindow на это:

public class ThemeWindow : Window
{
    static ThemeWindow()
    {
        StyleProperty.OverrideMetadata(typeof(ThemeWindow), new FrameworkPropertyMetadata(GetDefautlStyle()));
    }

    private static Style GetDefautlStyle()
    {
        if (defaultStyle == null)
        {
            defaultStyle = Application.Current.FindResource(typeof(ThemeWindow)) as Style;
        }
        return defaultStyle;
    }

    private static Style defaultStyle = null;
}

это на самом деле не решает вопрос, но это позволит вам достичь того, что вам нужно !

EDIT: смотрим DefaultStyleKey ссылка, четко указано, что он используется для стиль тема поиск. Это объясняет, почему он не найдет его в приложении.XAML или любой другой словарь. Он будет искать только в тематических словарях. Поэтому вам нужно либо определить свой стиль в словаре тем, либо использовать свойство Style напрямую, как в приведенном выше примере.


Я прихожу к следующему решению, уже обсужденному в stackoverflow. при загрузке приложения потребуется добавить компонент load.

См. Решение