10

I'm working on using XAML to create an object tree and one of the nodes looks like this:

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; } } 

My goal is essential to make the XAML and code behind as clean as possible which isn't the case right now where I'm creating wrapper properties for every function:

public static Func<bool> Func1 { get { return Method1; } } public static bool Method1() { //Do stuff here return true; } 

and the xaml looks like this for the above code:

<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> 

I would like to know if there's a quick and easy way to bind methods/functions to the Func property, I'm talking about the method here NOT the value of the executed method/function. (I can think of using some reflection magic in a valueConverter or inside the ExecuteMethod node/class but that just feels dirty and weird) An example of how I'd like the XAML to look:

<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> 

Thanks for any help in advance and sorry for the bad English grammar, it's not my native language :)

2 Answers 2

9

Thanks jbtule!

here's the solution if anyone wants it:

[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 } 
Sign up to request clarification or add additional context in comments.

Comments

7

I can think of couple ways to make it look cleaner but there isn't a binding syntax for what you are asking. I'm guessing what you would be most happy with would be writing your own markup extension so you could make it look like {d:StaticMethod Program.Method1}, but you would definitely have to use reflection, but it would be trivial to cache and would look better than a value converter.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.