【问题标题】:Binding of static method/function to Func<T> property in XAML将静态方法/函数绑定到 XAML 中的 Func<T> 属性
【发布时间】:2011-07-06 00:57:12
【问题描述】:

我正在使用 XAML 创建一个对象树,其中一个节点如下所示:

public class ExecuteMethod : INode
{
    #region Implementation of INode

    public bool Evaluate()
    {
        return Function != null && Function();
    }

    public string Name { get; set; }

    private string _type;
    public string Type
    {
        get
        {
            if (string.IsNullOrEmpty(_type))
            {
                _type = GetType().Name;
            }

            return _type;
        }
    }


    #endregion

    public Func<bool> Function { get; set; }

}

我的目标是使 XAML 和背后的代码尽可能干净,而现在我为每个函数创建包装器属性的情况并非如此:

public static Func<bool> Func1 { get { return Method1; } }

public static bool Method1()
{
    //Do stuff here
    return true;
}

对于上面的代码,xaml 看起来像这样:

<Root 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns="clr-namespace:XamlBT;assembly=XamlBT"  
xmlns:d="clr-namespace:TestBT;assembly=TestBT">
<Root.Child>
    <Sequence Name="sequence1" >
        <ExecuteMethod Name="e1.1" Function="{x:Static d:Program.Func1}" />
        <Selector Name="selector1" >
            <ExecuteMethod Name="e2.1" Function="{x:Static d:Program.Func1}"  />
        </Selector>
    </Sequence>
</Root.Child>

我想知道是否有一种快速简便的方法可以将方法/函数绑定到 Func 属性,我在这里谈论的是方法而不是执行的方法/函数的值。 (我可以考虑在 valueConverter 或 ExecuteMethod 节点/类中使用一些反射魔法,但这只是感觉肮脏和奇怪) 我希望 XAML 的外观示例:

<Root 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns="clr-namespace:XamlBT;assembly=XamlBT"  
xmlns:d="clr-namespace:TestBT;assembly=TestBT">
<Root.Child>
    <Sequence Name="sequence1" >
        <ExecuteMethod Name="e1.1" Function="{x:Static d:Program.Method1}" />
        <Selector Name="selector1" >
            <ExecuteMethod Name="e2.1" Function="{x:Static d:Program.Method1}"  />
        </Selector>
    </Sequence>
</Root.Child>

提前感谢您的帮助,抱歉英语语法不好,这不是我的母语 :)

【问题讨论】:

    标签: wpf xaml data-binding c#-4.0 binding


    【解决方案1】:

    我可以想出几种方法让它看起来更干净,但是对于您所要求的内容没有绑定语法。我猜你最满意的是writing your own markup extension,所以你可以让它看起来像{d:StaticMethod Program.Method1},但你肯定必须使用反射,但缓存起来很简单,而且看起来比值更好转换器。

    【讨论】:

      【解决方案2】:

      谢谢jbtule!

      如果有人想要,这就是解决方案:

      [MarkupExtensionReturnType(typeof (Func<bool>))]
      public class StaticMethodExtension : MarkupExtension
      {
          public StaticMethodExtension(string method)
          {
              Method = method;
          }
           [ConstructorArgument("method")]
          public string Method { get; set; }
      
          private Func<bool> _func;
      
          #region Overrides of MarkupExtension
      
          public override object ProvideValue(IServiceProvider serviceProvider)
          {
              if (_func == null)
              {
                  int index = Method.IndexOf('.');
                  if (index < 0)
                  {
                      throw new ArgumentException("MarkupExtensionBadStatic");
                  }
                  string qualifiedTypeName = this.Method.Substring(0, index);
                  if (qualifiedTypeName == string.Empty)
                  {
                      throw new ArgumentException("MarkupExtensionBadStatic");
                  }
                  IXamlTypeResolver service = serviceProvider.GetService(typeof(IXamlTypeResolver)) as IXamlTypeResolver;
                  if (service == null)
                  {
                      throw new ArgumentException("MarkupExtensionNoContext");
                  }
                  var memberType = service.Resolve(qualifiedTypeName);
                  var str = this.Method.Substring(index + 1, (this.Method.Length - index) - 1);
      
                  if (str == string.Empty)
                  {
                      throw new ArgumentException("MarkupExtensionBadStatic");
                  }
      
                  var reflectedFunc = memberType.GetMethod(str,
                                                           BindingFlags.FlattenHierarchy | BindingFlags.Public |
                                                           BindingFlags.Static);
      
                  if (reflectedFunc != null)
                  {
                      if (reflectedFunc.ReturnType == typeof(bool))
                      {
                          var v = Delegate.CreateDelegate(typeof(Func<bool>), reflectedFunc, true);
      
                          _func = (Func<bool>) v;
                      }
      
                  }
      
              }
      
              return _func;
          }
      
          #endregion
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-07-01
        • 2019-10-06
        • 2010-10-30
        • 2021-12-17
        • 2014-09-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多