none
.net 4.0 wpf cascading style and resource dictionary problem RRS feed

  • Question

  • I've recently upgraded a project from .net 3.5 to .net 4.0.  There were two breaking changes one of which I'll discuss here.

    We have several projects in the solution, one of which contains only the resource dictionaries for all the other projects.  We have one master resource dictionary that contains basically (LookAndFeel.xaml):

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

    In StackPanelStyle.xaml we have:

    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
      <LinearGradientBrush x:Key="BackgroundBrush" StartPoint="0,0" EndPoint="0,1">
        <GradientStop Color="#202020" Offset="0.0"/>
        <GradientStop Color="#404040" Offset="0.1"/>
        <GradientStop Color="#707070" Offset="0.9"/>
        <GradientStop Color="#808080" Offset="1.0"/>
      </LinearGradientBrush>
      <Style TargetType="{x:Type StackPanel}">
        <Setter Property="Background" Value="{StaticResource BackgroundBrush}" />
      </Style>
    </ResourceDictionary>

    (note these aren't the real styles but put here for demonstration purposes) 

    In my window, therefore, I have

    <Window x:Class="WPF4Issues.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow">
      <Window.Resources>
        <ResourceDictionary Source="LookAndFeel.xaml"/>
      </Window.Resources>
      <Grid>
        <Grid.RowDefinitions>
          <RowDefinition Height="*"/>
          <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="*"/>
          <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <StackPanel Grid.Row="0" Grid.Column="0" MinWidth="20" MinHeight="20" />
        <Image SnapsToDevicePixels="True" Grid.Row="0" Grid.Column="1" Source="Smiley.png"/>
        <StackPanel Grid.Row="1" Grid.Column="0" MinWidth="20" MinHeight="20"/>
        <StackPanel Grid.Row="1" Grid.Column="1" MinWidth="20" MinHeight="20" />
      </Grid>
    </Window>

    In my .net 4.0 project the styles aren't being used but if I change my target framework to .net 3.5 then the styles are properly used as they should be. 

    Anyone have any suggestions to get this cascading style type to work with .net 4.0?

    Friday, May 7, 2010 2:47 PM

Answers

All replies

  • I've found a bug for this listed in connect.

    https://connect.microsoft.com/VisualStudio/feedback/details/555322/global-wpf-styles-are-not-shown-when-using-2-levels-of-references

    Hopefully it will be resolved quickly.

    Thanks,
    Brian

    Friday, May 7, 2010 3:16 PM
  • Hi Brian,

    I think this is a known issue and the WPF team is working to fix it. See comments in the blog post by Rob Relyea "My StaticResource reference worked differently with WPF 4 RC than it does with WPF 4 RTM". There Rob suggested a workaround for the bug. In your case, modify your XAML like this:

    <Window.Resources>
      <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
          <ResourceDictionary Source="LookAndFeel.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    
        <!-- just add a style for sometype here workarounds the problem -->
        <Style TargetType="{x:Type Window}"/> 
      </ResourceDictionary>
    </Window.Resources>

    Hope this helps.

    Regards,
    Jie
    MSDN Subscriber Support in Forum
    If you have any feedback on our support, please contact msdnmg@microsoft.com


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    If you have any feedback, please tell us.

    The All-In-One Code Framework Project
    My Blog (in Simplified Chinese)
    Monday, May 10, 2010 6:23 AM
    Moderator
  • Jie,

    Thanks for this.  It worked as described.

    Brian

    Wednesday, May 12, 2010 11:45 PM
  • Hi Brian,

    You can also contact Microsoft Support to request a hotfix for this bug.

    And I'm marking my previous reply as answer for others to see the workaround (I think this one is a relatively common issue).

    Regards,
    Jie
    MSDN Subscriber Support in Forum
    If you have any feedback on our support, please contact msdnmg@microsoft.com


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    If you have any feedback, please tell us.

    The All-In-One Code Framework Project
    My Blog (in Simplified Chinese)
    Thursday, May 13, 2010 5:39 AM
    Moderator
  • This isn't a valid workaround for composite applications where you have multiple levels of resource dictionaries that are all referenced from the App.xaml. I can't say <Style TargetType="{x:Type Application}"/> b/c Application doesn't derive from FrameworkElement. Here is my scenario. This is the App.xaml.

    Application.Resources>
       <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
         <ResourceDictionary Source="/Photometry.SourceLibrary;component/Skins/DefaultSkin.xaml" />
        </ResourceDictionary.MergedDictionaries>
       </ResourceDictionary>
        <Style TargetType="{x:Type Application}"/>
      </Application.Resources>

    Then inside my DefaultSkin.xaml I have some common brushes and then dictionaries referenced like so:

    <ResourceDictionary.MergedDictionaries>
      <ResourceDictionary Source="/Photometry.SourceLibrary;component/Shared/Resources.xaml"/>
     </ResourceDictionary.MergedDictionaries>

    ..then inside my Resources.xaml file I have dictionaries referenced like so:

    <ResourceDictionary.MergedDictionaries>
      <ResourceDictionary Source="/Photometry.SourceLibrary;component/Shared/DropDownButton.xaml"/>
      <ResourceDictionary Source="/Photometry.SourceLibrary;component/Shared/Menu.xaml"/>
      <ResourceDictionary Source="/Photometry.SourceLibrary;component/Shared/TabControl.xaml"/>
     </ResourceDictionary.MergedDictionaries>
    Does anyone know of a workaround for this? Thanks.

     

    Thursday, May 27, 2010 6:46 PM
  • I have tried this workaround in my application but it didn't solve the issue. Can you suggest me anything else. Thank you a lot.
    Thursday, June 17, 2010 1:36 PM
  • Hi BBaurer

    I had the same problem.  I put <Style TargetType="{x:Type Application}"/> before </ResourceDictionary> in the DefaultSkin.xaml like this:

    <ResourceDictionary x:Class="PriceGenie.ResourceLibrary.Skins.DefaultSkin"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

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


    <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="/PriceGenie.ResourceLibrary;component/ControlStyles/Resources.xaml"/> </ResourceDictionary.MergedDictionaries> <Style TargetType="{x:Type Window}"/> </ResourceDictionary>

     

    And it worked for me.

    Monday, July 19, 2010 7:53 PM
  • Jie Wang, thank you for the workaround!

     

    I added  <Style TargetType="{x:Type Window}"/> to my App.xaml after I merged in a resource dictionary in a different assembly, and it worked! I guess it forces it to apply those merged dictionaries or something.

    • Proposed as answer by Kumaresh J Wednesday, May 7, 2014 7:21 AM
    Wednesday, December 15, 2010 9:02 PM
  • This doesn't work for Silverlight 4. Is there a workaround there?
    Wednesday, December 22, 2010 5:35 PM