views:

446

answers:

6

I've just removed a big memory issue for me, I used to merge our "Themes" resource dictionary in every xaml file instead of just in the app.cs.xaml.

However, after removing the merging in every file except the App.cs.xaml I've lost the design time styles/templates.

Please note: This only applies to the styles merged into our Themes.xaml (e.g. Color.xaml, Brushes.xaml - we have one for each type of style). Stuff defined directly in Themes.xaml (which we have none of..) works.

I see two solutions,

1) Have the merging commented out in XAML and just un-comment it when I want to work with the designs.

2) Have this in the default ctor of every control: (perhaps only works in Blend)

#if DEBUG
Resources.MergedDictionaries.Add(
                new ResourceDictionary()
                {
                    Source = new System.Uri(@"RD.xml")
                }
                );
#endif

There has to be a better way to get design time editing of pages and controls, anyone know?

Thank you!

A: 

Another way of doing it (the way we're going for now): Have a pre-build script comment out the merging in all XAML files.

Makes it harder to debug memory issues etc in DEBUG mode, but can be fully automated and fixes the issues for the final release.

andyhammar
A: 

The script idea doesn't seem like a good idea to me. You'd have so many "fake" revisions in your source control and my guess is that you'd have to spend a lot of time tweaking it.

I've been hoping that VS2010 and Expression Blend 3 will make big improvements in this area. Anyone try out the betas and know?

emddudley
A: 

You can add resource distionary in Resources of App.xaml, that works perfectly for me. Or may be i m not getting u.

viky
Not last time I tested on this very app. Let me try it again, I'll report back.
andyhammar
Ok, after some more investigating I've pinned it down to this: A plain RD in app.xaml works, but the merged dicts don't. I'll update the main question now.
andyhammar
A: 

I've just removed a big memory issue for me, I used to merge our "Themes" resource dictionary in every xaml file instead of just in the app.cs.xaml.

Sorry for the offtopic, but could you provide any proof-link to authoritative source which describes those issues? It's not like I consider you as non-authoritative... just want to know a little bit more about this issue since I'm using almost the same technique for merging dictionaries.

Thanks.

archimed7592
Sorry, I don't have any references for that. What I did was a lot of memory debugging, both with WorkingSet and MemDbg. With the only change between two runs of the app being that the dicts were and were not merged in every XAML file, I had about double the amount of mem used when the dicts were merged. (And MemDbg showed a lot more objects relating to my styles)
andyhammar
May be that's the amount, parses uses at loading stage? If afterwards that memory is reused by heap or freed by GC, then there is nothing to worry about.
archimed7592
I, too, encountered the issue. And debugged it pretty much. Basically by "merging" resource dictionaries they are not reused, they are inlined. So if you merge Brushes.xaml (100 brushes) to 5 controls, and each of them is instantiated 5 times you'll end up with 2500 brushes in memory.
arconaut
+4  A: 

What I do is add a class that inherits from ResourceDictionary and override the source property to check if IsInDesignMode is true.

If it is I set the source otherwise I leave the source blank (which effectivley prevents the dictionary from being merged at runtime)

public class BlendMergedDictionary : ResourceDictionary
{
 public bool IsInDesignMode
 {
  get
  {
   return (bool)DependencyPropertyDescriptor.FromProperty(
       DesignerProperties.IsInDesignModeProperty,
       typeof(DependencyObject)
       ).Metadata.DefaultValue;
  }
 }

 public new Uri Source
 {
  get { return base.Source; }
  set
  {
   if (!IsInDesignMode)
    return;

   Debug.WriteLine("Setting Source = " + value);
   base.Source = value;
  }
 }
}

Now when I need to reference the dictionary in Blend I merge in the dictionary like this

<ResourceDictionary.MergedDictionaries>
            <BlendHelpers:BlendMergedDictionary Source="Foo.xaml" />
</ResourceDictionary.MergedDictionaries>

You still have to "merge" in the dictionary in every file, but you don't pay the penalty of actually loading the dictionary at runtime. The merge is only there to support design time behavior.

Foovanadil
As an aside, the reason that merged dicts in Blend don't work is because of relative pathing. When blend is hosting your application it is doing so in it's own directory (where the Blend.exe is installed). When it is looking for your relative pathed dicts, it is starting in it's directory and dotting down the tree. Of course it won't find your dictionary there so it explodes.
Foovanadil
A: 
Jane
please post a question as a new question, not as an answer to my question
andyhammar