未应用WPF窗口样式

yptwkmov  于 2022-11-18  发布在  其他
关注(0)|答案(3)|浏览(151)

我有一个ResourceDictionary,其中包含应用程序中使用的控件的样式定义。
所有样式都已正确应用于窗口中的控件...但未应用窗口本身的ResourceDictionary中的样式。
这是ResourceDictionary中的XAML,其中包含要应用于窗口的样式:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:primatives="clr-namespace:System.Windows.Controls.Primitives;assembly=PresentationFramework"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Style TargetType="{x:Type Window}">
        <Setter Property="Background" Value="#FF121212"></Setter>
        <Setter Property="Height" Value="768"></Setter>
        <Setter Property="Width" Value="1024"></Setter>
    </Style>
<!-- .... -->
</ResourceDictionary>

这是我正在使用的窗口的XAML(尝试应用此样式):

<Window x:Class="TryingStyles"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="TryingStyles">
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Resources/StylesDictionary.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>    
    <StackPanel>
        <StackPanel Orientation="Horizontal">
            <Label Content="Label" Height="28" HorizontalAlignment="Left" Margin="12,12,0,0" Name="Label1" VerticalAlignment="Top" />
            <TextBox Height="23" HorizontalAlignment="Left" Margin="56,14,0,0" Name="TextBox1" VerticalAlignment="Top" Width="120" />
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <TabControl Height="206" HorizontalAlignment="Left" Margin="12,43,0,0" Name="TabControl1" VerticalAlignment="Top" Width="250">
                <TabItem Header="TabItem1" Name="TabItem1">
                    <Grid></Grid>
                </TabItem>
            </TabControl>
            <GroupBox Header="GroupBox1" Margin="268,43,12,12" Width="396"></GroupBox>
        </StackPanel>
    </StackPanel>
</Window>

在IDE的“设计”视图中查看窗口时,似乎应用了该窗口的样式,但在运行应用程序时,却未应用该样式。
有人知道我做错了什么吗?

mrphzbgm

mrphzbgm1#

您的问题似乎没有适当的解决方案。样式中的TargetType不管理派生类型。以下是两种替代方法:您可以在样式中放置一个键,并将该样式应用于所有窗口。

<!-- Resource file -->    
    <ResourceDictionary ...>
        <Style TargetType="{x:Type Window}" x:Key="WindowDefaultStyle">
            <!-- .... -->    
        </Style>
    </ResourceDictionary>

    <!-- Window file -->
    <Window Style="{DynamicResource ResourceKey=WindowDefaultStyle}">

也可以使用Style的BasedOn属性。

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:my="clr-namespace:WpfApplication1">
    <Style TargetType="{x:Type Window}" x:Key="BaseStyle">
        <Setter Property="Background" Value="#FF121212"></Setter>
        <Setter Property="Height" Value="768"></Setter>
        <Setter Property="Width" Value="1024"></Setter>
    </Style>

    <!-- Inherit from the BaseStyle and define for the MainWindow class -->
    <Style TargetType="{x:Type my:MainWindow}" BasedOn="{StaticResource ResourceKey=BaseStyle}" />
</ResourceDictionary>
vm0i2vca

vm0i2vca2#

很奇怪的是,它在设计器中工作,但在应用程序运行时却不工作。问题似乎出在您的Style的TargetType上。Wpf似乎无法将Window类与您的派生类TryingStyles匹配。
更改您的TargetType,它将工作:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:primatives="clr-namespace:System.Windows.Controls.Primitives;assembly=PresentationFramework"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:my="clr-namespace:WpfApplication1">
    <Style TargetType="{x:Type my:TryingStyles}">
        <Setter Property="Background" Value="#FF121212"></Setter>
        <Setter Property="Height" Value="768"></Setter>
        <Setter Property="Width" Value="1024"></Setter>
    </Style>
    <!-- .... -->
</ResourceDictionary>
plupiseo

plupiseo3#

我在这里已经很晚了,但是我发现了一个解决方案,可以让Style TargetType="{x:Type Window}"应用于应用程序范围内的每个窗口,正如人们所期望的那样。声明一下,这个解决方案不起作用的原因是,您创建的每个窗口都不是一个Window,而是一个从window派生的新类型(例如“MainWindow”),并且Style的TargetType不适用于派生类。总之:
首先,确保App.xaml定义了Startup属性;因此在<Application>标记中,可以添加Startup="Application_Startup"或其他任何要调用startup方法的内容。
然后,在App.xaml.cs中添加:

private void Application_Startup(object sender, StartupEventArgs e)
{
    FrameworkElement.StyleProperty.OverrideMetadata(typeof(Window), new FrameworkPropertyMetadata
    {
        DefaultValue = Application.Current.FindResource(typeof(Window))
    });
}

其中方法名称与App. xaml中作为Startup属性列出的内容相匹配。当然,如果已经有一个正在运行的现有启动方法,只需将包含在其中的代码添加到该方法中即可。
这基本上只是修复了这个问题,以便以“Window”为目标的无键样式将它们的更改应用到应用程序中的每个窗口,正如您可能预期的那样,没有这个代码片段也会发生这种情况。(当然,这是假设您的样式已经在应用程序范围内起作用,例如,通过将它包含在合并到App. xaml中的ResourceDictionary中。)

相关问题