Reference members of a StaticResource





5.00/5 (1 vote)
A static resource with a Path property. For example, it can be used to redirect command handling to a resource object.
A StaticResource with a Path property
Suppose you have a resource (sayMyResource
) which has some member (say MyMember
) which you want to access in an XAML file. Since the StaticResource
markup extension has no Path
property, this is not directly possible, if one cannot use a binding. Here I give an extension, StaticResourceEx
, which is the same as StaticResource
, but with a Path
property.
Usage:
<my:StaticResourceEx ResourceKey="MyResource" Path="MyMember"/>
The code for StaticResourceEx looks as follows:
class StaticResourceEx : StaticResourceExtension
{
public PropertyPath Path { get; set; }
public override object ProvideValue(IServiceProvider serviceProvider)
{
object o = base.ProvideValue(serviceProvider);
return (Path==null ? o : PathEvaluator.Eval(o, Path));
}
class PathEvaluator : DependencyObject
{
private static readonly DependencyProperty DummyProperty =
DependencyProperty.Register("Dummy", typeof(object),
typeof(PathEvaluator), new UIPropertyMetadata(null));
public static object Eval(object source, PropertyPath path)
{
PathEvaluator d = new PathEvaluator();
BindingOperations.SetBinding(d, DummyProperty,
new Binding(path.Path) { Source=source } );
return d.GetValue(DummyProperty);
}
}
}
The Motivating Example
I recently wanted to handle some commands in a non-UI component, which exists as a static resource of the main window. One solution is as follows:- Let the non-UI component expose the
CommandBinding
. - Add this binding to the main window's
CommandBindings
.
<Window.CommandBindings>
<my:StaticResourceEx ResourceKey="FindReplaceComponent" Path="FindBinding"/>
<my:StaticResourceEx ResourceKey="FindReplaceComponent" Path="ReplaceBinding"/>
<my:StaticResourceEx ResourceKey="FindReplaceComponent" Path="FindNextBinding"/>
</Window.CommandBindings>
Note that you cannot directly use a binding in this situation.
Limitations, and when not to use it
The first thing to say is that if you can use a binding, i.e., if you want to assign a dependency property, you should definitely do so. Also it is important that the resource's member you reference is available on startup, since the value is only queried once. Finally, in the command binding example above, the Visual Studio designer sometimes whines thatStaticResourceEx
is not a CommandBinding
. However, just recompiling removes this error. (If anyone knows how to remedy this, I'd be happy to know.)