Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / WPF

Reference members of a StaticResource

5.00/5 (1 vote)
7 Jan 2012CPOL1 min read 19.5K  
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 (say MyResource) 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:
XML
<my:StaticResourceEx ResourceKey="MyResource" Path="MyMember"/>

The code for StaticResourceEx looks as follows:
C#
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:

  1. Let the non-UI component expose the CommandBinding.
  2. Add this binding to the main window's CommandBindings.


The code for the second step in my example looks as follows:
XML
<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 that StaticResourceEx is not a CommandBinding. However, just recompiling removes this error. (If anyone knows how to remedy this, I'd be happy to know.)

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)