基本窗口的WPF样式未在App.xaml中应用,但在Themes / Generic.xaml中

时间:2013-01-17 16:32:48

标签: c# wpf wpf-controls

我正在为我的大部分窗口创建一个基本窗口类。显然,对此最好的解决方案是单独的类,以及适用于它的样式。

问题是我<Style ../>App.Resources没有应用ResourceDictionary。也就是说,如果它在外部App.xaml中定义,并合并到App.Resources的资源,或本地词典并合并,或内联到<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的{​​{1}}只是以下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,并将其放入应用程序的Themes/目录中。< / p>

我想知道为什么会发生这种情况。

我唯一的理论是,当WPF看到控件类型时,它将转到Themes,并扫描所有类型的ResourceDictionary,然后回退到Generic.xaml并加载它。这并不能解释为什么如果<Style />在合并的ResourceDictionary中可用,它将无法加载。 注意如果将MergedDictionary放入Generic.xaml,它会起作用,原因很明显。

我完全可以将ResourceDictionary合并到Generic.xaml中,如果这是我必须做的事情。我只想了解技术细节,了解为什么需要像这样。

此工作/工作的屏幕截图: Broken Image Working Image

2 个答案:

答案 0 :(得分:3)

我有一个简单的解决方法,允许您在app.xaml中设置样式。

在app.xaml中定义你的风格,如下所示:

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

将你的TheWindow改为:

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;
}

它并没有真正解决问题,但这可以让你实现你所需要的!

编辑:查看DefaultStyleKey引用,明确指出它用于主题样式查找。这就解释了为什么它不会在app.xaml或任何其他字典中找到它。它只会搜索主题词典。因此,您必须在主题词典中定义样式,或者直接使用Style属性,如上例所示。

答案 1 :(得分:0)

我遇到了stackoverflow中已经讨论过的以下解决方案。在加载应用程序时需要添加加载组件。

Refer Solution