Windows Style from ResourceDictionary don't apply

后端 未结 3 1057
一向
一向 2021-02-19 03:43

As I have multiple Windows in my application, I am looking for a solution that does not require me to set a binding on each Window.

<
相关标签:
3条回答
  • 2021-02-19 03:46

    This is the solution I used in my application. It lets me keep all my window styles together, and requires just a couple lines after the <Window.Resources> section.

    Do your Style like so:

    <Style x:Key="MyWindowStyle">
        <Setter Property="Window.Background" Value="AliceBlue"/>
    </Style>
    

    Then, in your Window, after </Window.Resources> include the following:

    <Window.Style>
        <Style BasedOn="{StaticResource MyWindowStyle}"/>
    </Window.Style>
    
    0 讨论(0)
  • 2021-02-19 03:56

    Add a new brush in your resource dictionary

    <SolidColorBrush x:Key="WindowBackground" Color="AliceBlue" />
    

    and in your WPF window simply set the required resource to the window background property

    <Window x:Class="GDD.Presentation.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="300" Width="300"
        Background="{StaticResource WindowBackground}">
    
    0 讨论(0)
  • 2021-02-19 03:57

    This appears to be caused by a combination of the order in which WPF loads/processes styles from nested ResourceDictionary, and the specifics of the Window class.

    Assume MainWindow is defined as per your post. Now put the following in Templates.xaml:

    <Style TargetType="{x:Type Window}">
        <Setter Property="Background" Value="Red"/>
    </Style>
    <Style TargetType="{x:Type Window}" x:Key="myStyle">
        <Setter Property="Background" Value="Green"/>
    </Style>
    

    If MainWindow has no style defined, then you will see that in the designer it appears with a red background. The designer is parsing the whole Xaml and loading the resource dictionary, and then drawing the results. The style is read before the window is drawn, and so the red background is applied.

    When you run the application, the window is created before the ResourceDictionary is applied. It looks for a default style (a style with x:Key="{x:Type Window}") before the nested ResourceDictionary is processed, and finds nothing. Therefore at runtime, the window appears with default colour. (This is the behaviour described in the comments above.) Remember that the style with x:Key="{x:Type Window}" has a default value that matches the Windows style.

    This is borne out if you use myStyle explicitly. If you add to your Window definition the attribute Style="{StaticResource myStyle}" you'll find that the designer fails, but you also get a run-time error, because myStyle hasn't been created at the time that the Window needs it. If you switch to Style="{DynamicResource myStyle}" then you'll see that it works as you hope, because DynamicResource will update once the ResourceDictionary has been parsed and the style included.

    So, applying this, you can fix the problem in one way by adding this to your Window element: Style="{DynamicResource {x:Type Window}}" - but this is cludgy. The better solution is to include your resource dictionary in the app.xaml file, where it will be parsed before any window is opened and thus available to all:

    <Application.Resources>
        <ResourceDictionary>
                <ResourceDictionary.MergedDictionaries>
                    <ResourceDictionary Source="Templates.xaml" />
                </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
    

    The real issue here is that your Window is not really a Window: it is a class that derives from Window and will in fact be MainWindow, Window2, etc... This means that the automatic style wireup for a Window will never work in this way, and some level of manual binding will unfortunately always be required.

    0 讨论(0)
提交回复
热议问题