WPF not applying default styles defined in MergedD

2019-03-10 18:54发布

问题:

In a WPF application I defined default control styles in separate resource dictionaries (e.g. "ButtonStyle.xaml"), and added them as merged dictionaries to a resource dictionary named "ResDictionary.xaml".

If I refer this "ResDictionary.xaml" as merged dictionary in my App.xaml, the default styles are not applied. However, if I refer the "ButtonStyle.xaml", it works correctly.

If I recompile the same code in .NET 3.5 or 3.0, it recognizes and applies the default styles referred in "App.xaml" through "ResDictionary.xaml", but not in .NET 4.0.

At runtime if I check the Application.Current.Resources dictionary, the default styles are there, but they are not applied, only if I specify the Style property explicitly in the Button control.

Are there any solutions to refer a resource dictionary (containig default styles) this way in .NET 4.0?


App.xaml:

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

ResDictionary.xaml:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="Default/ButtonStyle.xaml"/>
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

ButtonStyle.xaml:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Style TargetType="Button">
        <Setter Property="Background" Value="Yellow"/>
    </Style>
</ResourceDictionary>

回答1:

There is a sort-of fix for this, but I’ve only been able to make it work at the window level (not the application level).

In order to include a WPF 4.0 resource from a separate project, the resource must be added as a resource in the window’s code behind. The statement belongs in the window’s constructor, prior to the InitializeComponent method call:

public ControlsWindow()
{
    this.Resources = Application.LoadComponent(new Uri("[WPF 4.0 ResourceProjectName];Component/[Directory and File Name within project]", UriKind.Relative)) as ResourceDictionary;
    InitializeComponent();
}

Note: Replace the '[WPF 4.0 ResourceProjectName]' text with your resource's project name. Also, the '[Directory and File Name within project]' needs to be replaced with the relative location of the resource file (like 'Themes/StandardTheme.xaml')

I go into more details about this issue here.



回答2:

The best solution is to add a dummy default style in the resource dictionary where you merge all resources together.

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

<ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="Style/Button.xaml"/>
</ResourceDictionary.MergedDictionaries>

<Style TargetType="Control" BasedOn="{StaticResource {x:Type Control}}" />



回答3:

This could be caused by a known bug when there is a single style in application.resources within app.xaml when not using a startupuri.

The fix is to add an additional style like this...

...
   <Style x:Key="unused" />
</Application.Resources>

for more details check out this link.... http://bengribaudo.com/blog/2010/08/19/106/bug-single-application-resources-entry-ignored



标签: c# wpf .net-4.0