Accessing base class Resources in a WPF Page class - wpf

I've got a custom WPF Application base class which has a set of resources specified in XAML in the Application.Resources property. I've changed the build action to Page from ApplicationDefinition.
Now I have another project, and I changed the App class to inherit from my custom application base above. However, I can't find how to access the resources which were specified in the base class's XAML file.
How can I load and access those resources, merging it with my derived Application classes Resources?

One thing you might be able to do is to use a merged dictionary. Its not exactly "inherited" but it works. I would separate out your resources into a shared xaml dictionary file, and then reference it from both your base Application, as well as your inheriting.
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictonary Source="pack://application:,,,/ASSEMBLY;component/PATHTOSHAREDDICTIONARY"/>
</ResourceDictionary.MergedDictionaries>
<!-- More Resources can go here -->
</ResourceDictionary>
</Application.Resources>
I'm not sure how this is going to play with your Application, but it might be worth a shot. Good luck!
Note that ASSEMBLY and PATHTORESOURCEDICTIONARY will need to be replaced in your pack syntax.

Related

Shared WPF resources inside an activity designer library

I'm developing a bunch of custom activity designers, which contain custom controls, images, styles etc. The designer XAMLs are spread over several subdirectories in a library project (not a WPF application, therefore no app.xaml available)
I need a central place to store resources, just like the app.xaml in a regular WPF application.
Currently I use a projectdir\Properties\lib.xaml file like this:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ControlTemplate x:Key="TrafficLight">
...
</ControlTemplate>
</ResourceDictionary>
And reference this from all my designer XAMLs like this:
<sap:ActivityDesigner.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/ActDesLib;component/Properties/lib.xaml" />
</ResourceDictionary.MergedDictionaries>
where ActDesLib is the name of my assembly.
This does work, but it looks a bit clumsy. Is there a better way to do it?
Is there some "magic" app.xaml-like file that gets included automatically for a library project, without the need to add any special markup to the individual XAML files? That would make it so much easier to enforce a consistent style, even with multiple developers working on the different designers.
BTW: I tried to use relative pathes in the Source="..." attribute. This did not work when using my activities in a workflow inside VS2010, it could not find the resources then. With the absolute path, containing assembly name, it works fine. But is there no way that VS2010 or a rehosted designer can find out the path to the resource dictionary file automatically, with only relative references inside my XAMLs?

WPF Adding a 'Resource' Project to a solution with multiple WPF applications

I am developing three kiosk-like applications in WPF. They will share a similar look and feel, and I was hoping to create the projects all in the same solution. What I would like to do is add a project to the solution that just holds shared resources, such as fonts and images.
My question is, is it possible to share resources like embedded fonts across applications, and if so, what is the appropriate project type for this use? (class library? WPF user control?)
I would create a WPF Custom Control Library, then create a ResourceDictionary to hold the resources, where in the App.xaml of your start-up project I would link the Resource dictionary.
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/myResourceLibrary;component/myResourceDictionary.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
That way, you can just move the DLL around to whichever solution you want to use it in.

WPF - using styles/resources from another assembly

I'm new to WPF and struggling to use styles that live in a separate assembly. This is what I'm doing:-
I have a class library project with a \Themes folder containing a "generic.xaml" that merges a number of xaml files from a subfolder within \Themes:-
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Metro\CoreStyles.xaml" />
... etc ...
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
My solution also has a WPF application project, and in here the App.xaml merges in the resources from my library project like so:-
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MyThemeLibrary;component/Themes/generic.xaml"/>
... etc...
Standard stuff so far.
Finally, I have a third project - a WPF user control library. These controls use these common styles, typically with "Style={StaticResource SomeStyle}". I can run the app and it all looks fine, but the problem is I don't get design-time support when writing the user controls - the design surface is basically empty.
Another SO article suggested adding an App.xaml to the user control library project, and merging in the resources as above. This works and I get my design-time support, however I get an error when trying to build the solution:
Library project file cannot specify ApplicationDefinition element.
I have tried changing the App.xaml build action from "ApplicationDefinition" to "Page", as has been suggested elsewhere. This gets the build working but I lose the design-time support as the user controls can no longer see the styles.
Is there a way around this problem, or failing this, an alternative way of using styles from another assembly?
Thanks in advance
Andrew
The error message says it. You cannot use "pack://application..." syntax in a library project. You should do this in your wpf project.

Registering a custom URI protocol to handle custom resource loading from XAML

I'm working on a project where loose bits of XAML (and some associated IronPython code) will be dynamically loaded and executed by a client application. The client will be using a custom WCF service (and some local caching) to retrieve the XAML, backing scripts, and related resources (icons, images, etc..).
I would like to register a custom URI protocol/scheme to make it easier for the developers of the dynamic packages to reference their resources, like the following:
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="custom://MyPackage/Icons.xaml" />
<ResourceDictionary Source="custom://MyPackage/Styles.xaml" />
<!-- ^^^^^^ -->
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
</UserControl>
As far as I can tell, I can derive a custom UriParser and register it, but that only seems to be half the battle. The remaining work is to provide whatever component is necessary to resolve the custom URI and retrieve the required content.
Is it possible to provide or override functionality in WPF to allow it to call my custom data service when one of my custom URIs is encountered? Or, if this is impossible, is there any sort of alternative?
From what I understand, you need to create a class that derives from WebRequest and register it with WebRequest.RegisterPrefix.
As an alternative, I wonder if you could create a new class that inherits from ResourceDictionary (since it is not sealed) and provide a new definition for Source. This would let you intercept the value being set to Source then and run it against your custom UriParser. This would also allow you to easily update the ResourceDictionary with the results.

Silverlight: Multiple project sharing the same style files

I have multiple silverlight project that I would like to use the same styles, colour scheme, and some templated objects.
How do I accomplish this?
One way to do this would be to create a new silverlight class library which would be your shared theme/style assembly which would be referenced by the other silverlight projects. This assembly would have one or more Resource Dictionary XAML files in it which could define all of your styles, brushes and templates. You could even set up some cascading style hierarchies using the BasedOn attribute of the Style class.
You could then use MergedDictionaries to merge these styles into your application either at the App.xaml-level or on a page-level basis.
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/SharedThemeAssembly;component/MyStyles.xaml"/>
...other ResourceDictionaries to merge in...
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
You would then reference the shared styles / brushes as you normally would any other StaticResource.
There are two options, first as Dan indicates you could create a library that is shared by the other projects. If the clients access several of your projects and your projects use application library caching then you reduce the total download size.
The other approach is to create a Resource dictionary in one project, then add the same file to the other projects. Note in the Add Existing Item dialog the add button has a small drop down image, drop it down and then select "Add as Link".
This leaves the dicitionary as a simple Xaml file. One advantage I can see for this is to actually leave the dictionary file out of the Xap and just place it in the clientBin folder (or whatever the folder that the Xap is placed in). This approach allows all the Xaps to share the single dictionary (in the same way the first approach does) but allows the Xaml to be tweaked without messy rebuilds.

Resources