如何在app.xaml中设置默认的WPF窗口样式?

Noi*_*ves 63 wpf themes styles c#-3.0

我试图在我的app.xaml中为我的WPF Windows应用程序中的每个窗口设置默认样式.到目前为止,我在app.xaml中有这个:

<Application.Resources>
    <ResourceDictionary>
        <Style x:Key="WindowStyle" TargetType="{x:Type Window}">
            <Setter Property="Background" Value="Blue" />
        </Style>
    </ResourceDictionary>
</Application.Resources>
Run Code Online (Sandbox Code Playgroud)

通过专门告诉窗口通过以下方式使用此样式,我可以在运行应用程序(但不是VS设计器)时让窗口显示此样式:

Style="{DynamicResource WindowStyle}
Run Code Online (Sandbox Code Playgroud)

这有效,但并不理想.那么我该怎么做:

  1. 让所有窗口自动使用样式(所以我不必在每个窗口上指定它)?
  2. 有VS设计师展示风格吗?

谢谢!

Gis*_*shu 46

添加Ray所说的内容:

对于样式,您需要提供Key/ID或指定TargetType.

如果FrameworkElement没有明确指定的Style,它将始终使用自己的类型作为键来查找Style资源
- 编程WPF(Sells,Griffith)

如果提供TargetType,则该类型的所有实例都将应用样式.然而,衍生类型不会......似乎.<Style TargetType="{x:Type Window}">不适用于所有自定义派生/窗口.<Style TargetType="{x:Type local:MyWindow}">仅适用于MyWindow.所以选项是

  • 使用您指定的键控样式作为要应用样式的每个窗口的样式属性.设计师将展示风格的窗户.

.

    <Application.Resources>
        <Style x:Key="MyWindowStyle">
            <Setter Property="Control.Background" Value="PaleGreen"/>
            <Setter Property="Window.Title" Value="Styled Window"/>
        </Style>
    </Application.Resources> ...
    <Window x:Class="MyNS.MyWindow" Style="{StaticResource MyWindowStyleKey}">  ...
Run Code Online (Sandbox Code Playgroud)
  • 或者你可以从一个自定义的BaseWindow类派生(它有自己的怪癖),你可以在Ctor/Initialization/Load阶段设置一次Style属性.然后,所有派生将自动应用样式.但设计师不会注意到你的风格你需要运行你的应用程序才能看到正在应用的样式..我猜设计师只是运行InitializeComponent(这是自动/设计器生成的代码)所以XAML应用但不是自定义代码隐藏.

所以我会说明确指定的样式是最少的工作.无论如何,你可以集中改变风格的各个方面.

  • 最后一行"<Window x:Class ..."进入窗口的xaml def头而不是App.resources (2认同)

小智 21

知道这是多年以后,但因为这个问题还在这里......

  1. 在项目中创建资源字典(右键单击项目...)

    我将在Project下创建一个名为"Assets"的新文件夹,并将"resourceDict.XAML"放入其中.

  2. 将代码添加到resourceDict.XAML:

    <Style x:Key="WindowStyle" Target Type="Window" >
         <Setter Property="Background" Value="Blue" />
    </Style>
    
    Run Code Online (Sandbox Code Playgroud)
  3. 在Project XAML文件中,在Window下添加以下内容:

    <Window.Resources>
        <ResourceDictionary>
            <!-- Believe it or not the next line fixes a bug MS acknowledges -->
            <Style TargetType="{x:Type Rectangle}" />
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/Assets/resourceDict.XAML" />
            </ResourceDictionary.MergedDictionaries>
        <ResourceDictionary>
    </Window.Resources>
    
    Run Code Online (Sandbox Code Playgroud)

    引用以下网站:麻烦引用包含合并字典的资源字典 "有一个错误:如果所有默认样式都嵌套在三个深度(或更深)的合并字典中,则顶级字典不会被标记,因此搜索会跳过它的工作原理是在根词典中将默认样式放到某个东西上." 它似乎可靠地解决了问题.去搞清楚...

  4. 最后,在Window下,也许在Title之后,但在最后一个Window'>'之前:

    Style="{DynamicResource windowStyle}"
    
    Run Code Online (Sandbox Code Playgroud)
  5. 并且您需要将步骤3和4中的代码添加到您希望应用样式的每个项目中.

  6. 如果要使用渐变背景而不是纯色,请将以下代码添加到resourceDict.XAML:

    <LinearGradientBrush x:Key="windowGradientBackground" StartPoint="0,0"
            EndPoint="0,1" >
    <GradientStop Color= "AliceBlue" Offset="0" />
    <GradientStop Color= "Blue" Offset=".75" />
    </LinearGradientBrush>
    
    Run Code Online (Sandbox Code Playgroud)
  7. 并修改样式设置器以获取背景颜色:

    <Setter Property="Background" Value="{DynamicResource
            windowGradientBackground}" />
    
    Run Code Online (Sandbox Code Playgroud)

需要在每个project.XAML文件中重复步骤3和4,如上所述,但是,嘿,您可以在整个解决方案中获得统一的Windows!同样的过程可以应用于任何你想拥有统一外观的控件,按钮等等.

对于那些迟到的人来说,希望这会有所帮助,因为我确信原始海报在几年前就已经弄明白了.

保罗


Ray*_*sen 8

设计器无法正常工作,因为您正在指定DynamicResource.请将此更改为StaticResource,一切都会好的.

要应用于所有窗口,您应该从样式中删除x:Key.设置TargetType隐式地将x:Key设置为TargetType中的任何内容.但是,在我的测试中,这不起作用,所以我正在研究它.

如果我将TargetType设置为x:Type TextBlock,设计师工作得很好,它似乎只是显示不同行为的Window.


STi*_*eTT 5

您可以将此代码添加到App.xaml.cs文件中:

        FrameworkElement.StyleProperty.OverrideMetadata(typeof(Window), new FrameworkPropertyMetadata
        {
            DefaultValue = Application.Current.FindResource(typeof(Window))
        });
Run Code Online (Sandbox Code Playgroud)

此后,应用于该Window类型的样式也将应用于从其派生的所有类型Window