65.9K
CodeProject 正在变化。 阅读更多。
Home

引用 StaticResource 的成员

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2011年3月27日

CPOL

1分钟阅读

viewsIcon

20049

一个带有 Path 属性的静态资源。例如,它可以用来将命令处理重定向到资源对象。

带有 Path 属性的 StaticResource

假设你有一个资源(比如 MyResource),它有一些成员(比如 MyMember),你想在 XAML 文件中访问它。由于 StaticResource 标记扩展没有 Path 属性,如果不能使用绑定,则这直接是不可能的。在这里,我提供一个扩展,StaticResourceEx,它与 StaticResource 相同,但具有一个 Path 属性。用法
<my:StaticResourceEx ResourceKey="MyResource" Path="MyMember"/>
StaticResourceEx 的代码如下所示
    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);
            }
        }
    }

激励示例

我最近想在一个非 UI 组件中处理一些命令,该组件作为主窗口的静态资源存在。一种解决方案如下
  1. 让非 UI 组件公开 CommandBinding
  2. 将此绑定添加到主窗口的 CommandBindings
我的示例中第二步的代码如下所示
<Window.CommandBindings>
   <my:StaticResourceEx ResourceKey="FindReplaceComponent" Path="FindBinding"/>
   <my:StaticResourceEx ResourceKey="FindReplaceComponent" Path="ReplaceBinding"/>
   <my:StaticResourceEx ResourceKey="FindReplaceComponent" Path="FindNextBinding"/>
</Window.CommandBindings>
请注意,在这种情况下你不能直接使用绑定。

限制以及何时不使用它

首先要说的是,如果你可以使用绑定,即如果你想分配一个依赖属性,你应该绝对这样做。此外,重要的是你引用的资源的成员在启动时可用,因为该值只查询一次。最后,在上面的命令绑定示例中,Visual Studio 设计器有时会抱怨 StaticResourceEx 不是一个 CommandBinding。但是,重新编译可以消除此错误。(如果有人知道如何解决这个问题,我很乐意了解。)
© . All rights reserved.