It’s great that you can reference other objects in a resource dictionary in a XAML file. This makes it particularly interesting to me, since I go the whole hog and almost everything is a resource. For example, in my application (its a sort of scene graph), textures, materials and even animations are resources which other objects can reference. This makes things easier for me, allowing one instance of a potentially costly resource (like a large texture, or a vertex/pixel shader) to be used by multiple consumers. I suppose the same example could be applied to other cases as well. Resource sharing is a good thing, period. Well … this comes with its own set of problems with Xaml. Unless you hand-write all the XAML, StaticResource is practically useless unless you are guaranteed to have no forward references. This is understandable, and even the MSDN documentation says so quite clearly. The alternative is to use DynamicResource to resolve these references. Or so it says.
Trying it out, it seems that DynamicResource returns an internal class, ResourceReferenceExpression from ProvideValue, which is a way to tell the XAML parser to defer resolving this expression. But how and when does the expression actually get resolved? Its supposed to be resolved the first time its accessed, which unfortunately doesn’t seem to be the case. The resolving part seems to be tied down to a method (GetRawValue) that assumes the objects are derived from FrameworkElement. It also seems there’s no way to do any of this yourself since almost everything of any value is internal or sealed. All’s not lost, however, since DynamicResource is not sealed
. See, while we could very well write a custom markup extension, its ProvideValue would have to return null when XamlReader invokes it. This is a problem, and many objects won’t work properly when we do this. The alternative is to derive from DynamicResource, and return base.ProvideValue which is a ResourceReferenceExpression. At the same time, we note down the resources that require resolving in a static table. We can then use this table after the load to resolve all references. Attached is a VS2008 project that implements a ResourceExtension markup extension. There are some limitations to the code I’ve written, for example: it doesn’t take care of a resource reference that references another. For this ,we need to resolve in a particular order. But you get the idea, right?
So far, there’s no mention of how to write expressions to a XAML file. XamlWriter just wont do, since it will write the value of the property, and not the expression used to calculate it. Next time, we’ll talk about some a custom XamlWriter and some problems in that context.