将静态方法/函数绑定到 XAML 中的 Func<T> 属性
Posted
技术标签:
【中文标题】将静态方法/函数绑定到 XAML 中的 Func<T> 属性【英文标题】:Binding of static method/function to Func<T> property in XAML 【发布时间】: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>
提前感谢您的帮助,抱歉英语语法不好,这不是我的母语 :)
【问题讨论】:
【参考方案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
【讨论】:
以上是关于将静态方法/函数绑定到 XAML 中的 Func<T> 属性的主要内容,如果未能解决你的问题,请参考以下文章