2011-02-28 11 views
8

estoy trabajando en el uso de XAML para crear un árbol de objetos y uno de los nodos se parece a esto:La unión del método/función estática a Func <T> propiedad en 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; } 

} 

Mi objetivo es esencial para que la XAML y código detrás de lo más limpio posible, que no es el caso en este momento en que estoy creando propiedades de contenedor para cada función:

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

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

y el XAML se parece a esto para el código anterior:

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

me gustaría saber si hay una manera rápida y fácil para unirse métodos/funciones a la propiedad Func, estoy hablando acerca del método que aquí no el valor del método/función ejecutada. (Puedo pensar en utilizar un poco de magia reflejo en un valueConverter o en el interior del nodo/clase ExecuteMethod sino que sólo se siente sucio y raro) Un ejemplo de cómo me gustaría el XAML para mirar:

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

Gracias por cualquier ayuda de antemano y disculpa por la mala gramática del inglés, no es mi lengua materna :)

Respuesta

5

Puedo pensar en dos maneras para que se vea más limpio pero no hay una sintaxis vinculante para lo que eres preguntando. Supongo que con lo que sería más feliz sería writing your own markup extension, por lo que podría hacer que se vea como {d:StaticMethod Program.Method1}, pero definitivamente tendría que usar reflexión, pero sería trivial caché y se vería mejor que un convertidor de valor.

5

Gracias jbtule!

aquí está la solución si alguien lo quiere:

[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 
} 
Cuestiones relacionadas