Rud*_*ser 10 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)));
}
}
Run Code Online (Sandbox Code Playgroud)
这是<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>
Run Code Online (Sandbox Code Playgroud)
的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>
Run Code Online (Sandbox Code Playgroud)
现在,正如所述,如果你把它Style放在自己的ResourceDictionary,并包括它像这样:
<App.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Themes/ThemeWindow.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</App.Resources>
Run Code Online (Sandbox Code Playgroud)
.. 这是行不通的.如果你直接将样式内嵌App.Resources,它就不起作用.
我能找到它的唯一情况是调用ResourceDictionaryxaml Generic.xaml,并将其放入Themes/应用程序的目录中.
我想知道为什么会发生这种情况.
我唯一的理论是,当WPF看到一个控件类型时,它将转向Themes,并扫描所有ResourceDictionary类型的类型,然后回退Generic.xaml并加载它.这并不能解释为什么如果<Style />在合并中可用,它将无法加载ResourceDictionary.请注意,如果MergedDictionary放入,它确实有效Generic.xaml,原因很明显.
我具有合并完全正常的ResourceDictionary进入Generic.xaml,如果这是我必须做的.我只想了解技术细节,了解为什么它需要像这样.
这个不工作/工作的屏幕截图:

我有一个简单的解决方法,允许您在 app.xaml 中设置样式。
在 app.xaml 中定义您的样式,如下所示:
<Style x:Key="{x:Type testing:ThemeWindow}" TargetType="{x:Type testing:ThemeWindow}">
Run Code Online (Sandbox Code Playgroud)
并将您的 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;
}
Run Code Online (Sandbox Code Playgroud)
它并不能真正解决问题,但可以让您实现您所需要的!
编辑:查看DefaultStyleKey参考,它清楚地表明它用于主题样式查找。这解释了为什么它在 app.xaml 或任何其他字典中找不到它。它只会在主题词典中搜索。因此,您要么必须在主题词典中定义样式,要么像上面的示例一样直接使用 Style 属性。