Upgrading/Migrating to .net 4.0, two gotcha’s I found

Recently while upgrading a large project to .net 4.0 we ran into two problems. The first was simply that none of our xaml dictionaries were styling anything. The second was that all of our images looked horrible. These two problems aren’t mentioned anywhere by Microsoft in their guide to migrating to .net 4.0.

The first problem relates to merged dictionaries within a dictionary. In our project we have a master dictionary in a common project. All other projects call this common project. The common project contains only the xaml resource dictionaries. Our main dictionary looks kind of like:

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

Virtually every element in our application is styled via this dictionary. This creates a clean set of styles in seperate files that makes maintenance of these really simple. The problem is that in .net 4.0 none of the styles in these dictionaries were being applied. It seemed like .net 4.0 just wouldn’t go down into the resource dictionaries and get the proper styles. After posting a question in the msdn forums I took a look around Connect (Microsoft’s listing of bugs) and found that someone else had the same problem.

Fortunately one of the MSDN moderators came to my rescue and posted a workaround. Oddly enough all you have to do is include an empty style after the merged dictionary and everything starts working again. Our new master resource dictionary looks something like:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    >
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="ComboBoxStyle.xaml"></ResourceDictionary>
        <ResourceDictionary Source="ButtonStyle.xaml"></ResourceDictionary>
   </ResourceDictionary.MergedDictionaries>
   <Style TargetType="{x:Type Window}"/>
</ResourceDictionary>

and now all cascading styles are being applied correctly.

The second problem has to do resizing and scaling of images. Once again I started with a post on MSDN forums and then went and took a look around connect (I really should begin starting at Connect). It seems that in .net 4.0 in order to increase the effeciency of everything they changed the default rendering of images from Fant (extremely high quality) to Low quality. Not finding any easy solutions I simply changed our master resource dictionary from as show above to:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    >
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="ComboBoxStyle.xaml"></ResourceDictionary>
        <ResourceDictionary Source="ButtonStyle.xaml"></ResourceDictionary>
   </ResourceDictionary.MergedDictionaries>
   <Style TargetType="{x:Type Window}"/>
       <!--Fix for images rendering in low quality-->
   <Style TargetType="{x:Type Image}">
      <Setter Property="RenderOptions.BitmapScalingMode" Value="HighQuality"/>
   </Style>
</ResourceDictionary>

so that images would always defualt to rendering in High Quality. After I created this solution someone posted as a workaround in Connect just to add:

RenderOptions.SetBitmapScalingMode(this, BitmapScalingMode.HighQuality);

to the constructor of your main window and this will inherit to all images by default. I haven’t tried this solution and I’m not sure what would happen if you have projects other than the main project that open their own windows. It would seem like this should be a global setting since you’re setting the static in RenderOptions and this should work fine. For us this was unneeded since every window in all our projects calls the xaml shown above.

Well, if we run into anything else I’ll post it here but these were the only two issues we’ve found so far. It’s been a big benefit to upgrade for us to .net 4.0 if for no other reason then to have Parallel.For and Parallel.ForEach.

Thanks,
Brian

Comments (4)

  1. Brian,

    I was wondering if you’re using explicit styles in your resource dictionaries? I have a similar setup where I keep all my styles in resource dictionaries in a separate project. I’ve tried various ways of adding them to the App.xaml, App.xaml.cs, and [window name].xaml files, but none of them work for both explicit and implicit styles (including the one you outlined above). The only way I’ve been able to get them to work is to add the style via the codebehind at the window level:

    public SampleWindow()
    {
    this.Resources = Application.LoadComponent(
    new Uri(“[WPF 4.0 ThemeProjectName];Component/Themes/Theme.xaml”, UriKind.Relative)) as ResourceDictionary;
    InitializeComponent();
    }

    I go into more details about the troubles I’ve had with this issue at: http://www.wpfreakystyley.com/News/ResourcesIssues.aspx

    Well, any help or insight you could provide would be very useful.

    Thanks Brian!

    – John

  2. Derek

    The empty style fix doesn’t seem to work for Silverlight projects. It still won’t find styles in merged dictionaries. Is there a workaround for this?

  3. Derek,

    We’ve done two silverlight projects where I work (one of which I was the lead on) and neither was of the complexity where we needed styles broken out to the level referenced in the post. Unfortunately I don’t know of a workaround for you.

    Thanks,
    Brian

  4. Derek

    Hi Brian,

    Thanks for the reply. It turns out the problem I found isn’t exactly related to your issue. It’s a problem with how SL loads resource dictionaries. Dictionaries loaded first aren’t available to those loaded later.

    I implemented this solution and it works fine:
    http://stackoverflow.com/questions/4152955/silverlight-shared-mergeddictionaries

    Thanks for being on the way to finding it!
    Derek

Leave a Reply