Mike Taulty's Blog
Bits and Bytes from Microsoft UK
Blend Bits 7: Be Resourceful

Blogs

Mike Taulty's Blog

Elsewhere

Archives

Resources are easy enough to understand.

Lots of elements used in XAML markup have a little dictionary of resources associated with them that can store an object of any type as long as it has a key associated with it (except in one case which I’ll come back to in a different post about Styles).

An element at a particular point in a UI hierarchy defined in XAML can then reference resources using the {StaticResource} markup extension and get the resource resolved. That resolution involves scanning “up” the UI hierarchy looking for an appropriately named resource and that search also includes “application level resources” defined in an app.xaml file.

Dictionaries of resources can be put into separate files and then merged together to form one bunch of resources.

Blend supports all of that. If I create a blank, new Silverlight project then I get by default an App.xaml file and a MainPage.xaml file and over on the Resources Panel/Window I see that I’ve no resources right now;

image

but it’s “interesting” in that it shows me that there are 2 XAML files where resources might be placed and that within my MainPage.xaml it also shows me my UserControl as a place where resources might be put – as far as I know that UserControl will always show up there.

I’m not 100% sure of the algorithm that this Resources panel uses to decide what to show – it seems to “do the right thing” which, as far as I can tell, means that it will show;

  1. The top level UserControl
  2. Any current selection
  3. Any other object that has a resource dictionary that is not empty

Making Resources

Why not make a resource? If I go and draw out a Rectangle on the design surface and set its foreground to some solid colour brush like this lovely blue;

image

then I might well want to re-use that as a brush elsewhere so I can go and click on the “advanced options” box to the right of the Fill value – that is, the little white box to the right in order to raise a menu which lets me “Convert to New Resource”…

image

and Blend will then raise a dialog for me;

image

which allows me to define the key for the resource and also allows me to define it in one of a number of places;

  • App.xaml – global to the application
  • in one of a number of places in the current document ( in this case, MainPage.xaml )
    • NB: the places listed here seem to match those that show up in the resources panel which, I’m sure, is not coincidental Smile
  • in a new or existing resource dictionary

If I select App.xaml for the moment then I see my Resources panel update;

image

which shows me that I have the BlueBrush defined in App.xaml and it also lets me edit that brush resource inline in the resources panel;

image

and it also offers me a 2nd view which shows me which elements are using which resources if I click the little button circled below to switch “tabs”;

image

and it also ( is there no end??!?! ) updates the “advanced options” button next to my Fill value in the Properties panel to a green colour which indicates “this is not a local value, it comes from a resource”;

image

Just to illustrate that I can pretty much make a resource out of anything, I can take the Rectangle’s Width property and do the same thing to make it into a resource as well;

image

and if I follow the same procedure to put this as a resource into App.xaml then I now see 2 resources in there;

image

and, once again I can edit that definition in-line by just typing a different value.

If I wanted to “refactor” my resources so they were perhaps not in App.xaml but were, instead, defined as belonging to the UserControl in my MainPage.xaml then I can do that just by drag/drop;

image

image

Let’s say I’ve got something slightly more complex going on. Let’s say I have these Grids and this Ellipse;

image

and I use the same method to take the pink colour of the Ellipse and turn it into a resource. If I go with the “current document” then the dialog offers me;

image

but if I had some resources already present in (say) the red grid and the green grid then it would offer me;

image

which is the same set of places the Resources panel is showing ( when I’ve no selection made on the artboard );

image

If I wanted to use a resource dictionary instead of going with one of these locations then I could ( for instance ) take a TextBlock like this one;

image

and raise the dialog on one of its properties ( let’s say FontSize – NB: this isn’t a great example because I’d usually use a Style for this );

image

and I can extract that out to a resource dictionary;

imageimageimage

and then the Resources panel updates to show me the new dictionary and that it has been merged into the “global” dictionary owned by my App.xaml;

image

If I had a separate ( Silverlight library ) project in my solution with a reference between the two projects and was working in there as below;

image

then the “make new resource” window will still allow me to put that resource into App.xaml or into the resource dictionary MyResources.xaml both of which actually live in the main project;

image

That "feels” a little odd but I can see circumstances where you’d want to do it. Alternatively, of course, I can put it into the local document or into a new resource dictionary in the library project and then have that dictionary merged into the one in app.xaml.

Using Resources

Once I’ve got a resource, using it is pretty easy. Here, I’ve got a red grid that defines a String resource called “resourceText” and then there’s a green grid that contains a TextBlock;

image

I can drag the resource to the TextBlock if I want to and Blend will ask me what I was hoping to achieve based on the type of the resource in question;

image

or I can visit the property over in the properties window and use the Advanced Options button;

image

and if I had multiple resources available (e.g. at the app.xaml level and at the userControl level ) then it’ll show me all that apply;

image

and if I have more than one project in the solution like this set up;

image

where I’ve got an app referencing a library and both the app and the library have resource dictionaries present and I’ve defined 4 brushes;

  • app.xaml – appLevelRedBrush
  • appResourceDictionary.xaml – appLevelDictionaryPinkBrush
  • libraryResourceDictionary.xaml – libraryDictionaryBlueBrush
  • MainControl.xaml – libraryMainControlGreenBrush

then when I’m looking for a brush resource to fill an ellipse on my MainControl.xaml which is in the library project I see;

image

that is – I see the brush that is locally defined in the same XAML file ( green ) but I also see those that surface themselves at the application level either directly or through merged dictionaries ( one of which is coming from the library itself ).

The resources pane is showing this;

image

Whereas if I was working in the main project on MainPage.xaml then I would see possible brushes for my Ellipse of;

image

as, clearly, the green brush isn’t visible at all outside of the file and project that it was defined in.

So…lots of niceties in the environment around defining and re-using resources Smile


Posted Thu, Sep 9 2010 7:34 PM by mtaulty

Comments

Josh wrote re: Blend Bits 7: Be Resourceful
on Thu, Sep 9 2010 7:47 PM

Would help to see the XAML that is produced when more than one resouce dictionary is used in your user control. I have run into a problem where a resource can't be resolved due to the order of resources defined in a resource dictionary...

Anonymous wrote re: Blend Bits 7: Be Resourceful
on Fri, Sep 10 2010 6:34 AM

Very Help full

ideaindustries.net wrote re: Blend Bits 7: Be Resourceful
on Fri, Sep 10 2010 8:10 PM

Any idea how to handle this scenario: I import from photoshop and the layer is editable...lets say it's text. It imports as a textblock. All the attributes are declared inline. I want to promote this to a style. What is the best way? Currently I right click...create an empty style, and then "set" each of those properties to the same value they already had inline. This is even more painful because if something like horizontalalignment=center is declared inline and then you set it in the style to horizontalalignment=left (to get it to appear in the style) you cant change it back to center in the properties window, you have to edit it by hand in the xaml.

Mike Taulty's Blog wrote Blend Bits 22–Being Stylish
on Fri, Feb 11 2011 11:18 AM

I’m amazed to find that I got so far into this series of posts around Blend without writing a post about

Mike Taulty's Blog wrote Blend Bits 23–Templating Part 1
on Fri, Feb 11 2011 2:47 PM

One of the real strengths of Expression Blend is in its deep understanding of control templates. Visual