10

我正在为我的大多数窗口创建一个基窗口类来派生。显然,最好的解决方案是一个单独的类,以及适用于它的样式。

问题是<Style ../>I have 在App.Resources. 也就是说,如果它是在 external 中定义的ResourceDictionary,并合并到App.xaml's 资源中,或者是本地字典并合并,或者内联到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就是下面的 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/应用程序的目录中。

我想知道为什么会这样。

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

如果那是我必须做的,ResourceDictionary我完全可以不必合并。Generic.xaml我只是想了解一下为什么它需要这样的技术细节。

这个不工作/工作的截图: 破碎的图像 工作图像

4

2 回答 2

3

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

在 app.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;
}

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

编辑:查看DefaultStyleKey参考,明确说明它用于主题样式查找。这就解释了为什么它不会在 app.xaml 或任何其他字典中找到它。它只会在主题词典中搜索。所以你要么必须在主题字典中定义你的风格,要么像上面的例子一样直接使用 Style 属性。

于 2013-01-17T16:40:45.067 回答
0

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

参考解决方案

于 2013-01-17T17:26:50.987 回答