Those who are no stranger to wpf, and who strive to separate out their work across multiple projects to maintain order with a chaotic world; will have no doubt come across the WPF Pack Uri; and more specifically, the authority. This blog is based on the scenario that you are maintaining your resources in an assembly separate to your executable assembly.

Pack Uri’s in their absolute state can look something like this.

pack://application:,,,/ApplicationResources;component/Cursors/a-custom-cursor.cur

There are two settings you will come across that are directly related to the authority. These settings are…

application
(which is the option selected in the above example of an absolute pack Uri)

&

siteoforigin

Starting with a simple wpf application. Let us begin…

ProjectSetup

The application has a simple structure. A project for the application, and a second project to hold the resources we will use in this application. I have already added a folder to the resources project called ‘Cursors’. In which we’ll add as it says; our custom cursors.

Now at this point we can pause a moment to think. To think about how we want to output our custom cursors when the application is built. Do we either include them as a resource embedded in the ‘ApplicationResources’ assembly, or do we copy the file to the output folder, in a folder called cursors and grab the cursor from there?

How you do this is of course your decision and how you prefer to work it. Depending on what your choice is, let’s now look at how your decision effects the choice over which authority to use.

Application

The application authority is the default, and this is why…

I’ve added a cursor to the ApplicationResources project into its relevant folder.

.AddedCursor

Now if we take a look at the properties of that newly added cursor, we see the following…

CursorProperties

Two things to note here. Firstly, the build action is set to ‘Resource’ and we are not copying the file to the output directory. We don’t need to copy the file to the output directory because we are embedding it as a resource directly into the assembly. As the ApplicationResources project is referenced by the main project, we will see something like this when we build the application in our output directory.

OutputEmbeddedResources

Note the size of the ‘ApplicationResource.dll’, it’s this size because it has the ‘a-cursom-cursor.cur’ embedded in it; all nicely tucked away for the application to consume at will.

So now we wish to consume this cursor in our application and we shall do so via a pack Uri using the application authority. In the XAML I’m loading the cursor as a resource, using the Pack Uri thusly…

CursorResourceApplicationUri

And that is it. We have a button that has a custom cursor when we hover over it with the mouse, and the cursor is being retrieved by a Pack Uri using ‘application’ as the authority. One word of caution however, WPF has a funny tendency to throw its toys out the pram when you bring in new resources from other assemblies. If you finding it doing so, you can pacify it by doing a clean and rebuild.

As ‘application’ is the default authority, we do have the option here to shorten that Uri. You will be able to come away clean with the following…

/ApplicationResources;component/Cursors/a-custom-cursor.cur

And not have wpf slap you over the head about it.

Site Of Origin

Firstly, unlike we mentioned above, a site of origin Uri must be absolute; there are no ways to shorten the Uri to make things look tidy here.

Going back to when we added the cursor, we need to change a few settings on that file. Those settings are as shown below…

CursorPropertiesSiteOfOrigin

Changing the Build Action to ‘Content’ and setting the Copy to Output Directory to anything but ‘Do not copy’, I went for ‘Copy Always’; which produces for us what we see below in our output directory after a new build.

OutPutDirectorySiteOfOrigin

Note the size of the ‘ApplicationResources.dll’, and in our Cursors folder…

CursorInFolder

Now, at this point we have not made any changes to the Pack Uri in our application. We can build and run this application, but when we reach the point of using the cursor. WPF won’t just throw the toys out the pram, it will proceed to pick the pram up and throw it at you while shouting naughty words in ten different languages. Score one to .NETs culture support!

So, to avoid such a spectacle, let us make the needed changes to that Pack Uri so we can access the cursor again. And what we end up with is something that looks like this…

XamlSiteOfOrigin

As you may have noticed, the assembly reference is no longer present. We don’t need it as the file is no longer associated with the assembly when we build.

And that’s it, from this page of babble we can see how we use the two different authorities when building a WPF Pack Uri and how each is useful depending on the chosen architecture. ‘Application’ authority can lead us to resources embedded inside our assemblies. ‘Siteoforigin’ allows us to access resources relative to the location of our application’s executable after output.

Advertisements