@ -9,24 +9,30 @@ namespace Avalonia.Markup.Data.Plugins
{
class MethodAccessorPlugin : IPropertyAccessorPlugin
{
public bool Match ( object obj , string property Name)
= > obj . GetType ( ) . GetRuntimeMethods ( ) . FirstOrDefault ( x = > x . Name = = propertyName ) ! = null ;
public bool Match ( object obj , string method Name)
= > obj . GetType ( ) . GetRuntimeMethods ( ) . Any ( x = > x . Name = = methodName ) ;
public IPropertyAccessor Start ( WeakReference reference , string property Name)
public IPropertyAccessor Start ( WeakReference reference , string method Name)
{
Contract . Requires < ArgumentNullException > ( reference ! = null ) ;
Contract . Requires < ArgumentNullException > ( property Name ! = null ) ;
Contract . Requires < ArgumentNullException > ( method Name ! = null ) ;
var instance = reference . Target ;
var method = instance . GetType ( ) . GetRuntimeMethods ( ) . FirstOrDefault ( x = > x . Name = = property Name) ;
var method = instance . GetType ( ) . GetRuntimeMethods ( ) . FirstOrDefault ( x = > x . Name = = method Name) ;
if ( method ! = null )
{
if ( method . GetParameters ( ) . Length + ( method . ReturnType = = typeof ( void ) ? 0 : 1 ) > 8 )
{
var exception = new ArgumentException ( "Cannot create a binding accessor for a method with more than 8 parameters or more than 7 parameters if it has a non-void return type." , nameof ( method ) ) ;
return new PropertyError ( new BindingNotification ( exception , BindingErrorType . Error ) ) ;
}
return new Accessor ( reference , method ) ;
}
else
{
var message = $"Could not find CLR method '{propertyName}' on '{instance}'" ;
var message = $"Could not find CLR method '{method Name}' on '{instance}'" ;
var exception = new MissingMemberException ( message ) ;
return new PropertyError ( new BindingNotification ( exception , BindingErrorType . Error ) ) ;
}
@ -41,9 +47,7 @@ namespace Avalonia.Markup.Data.Plugins
var paramTypes = method . GetParameters ( ) . Select ( param = > param . ParameterType ) . ToArray ( ) ;
var returnType = method . ReturnType ;
// TODO: Throw exception if more than 8 parameters or more than 7 + return type.
// Do this here or in the caller? Here probably
if ( returnType = = typeof ( void ) )
{
if ( paramTypes . Length = = 0 )
@ -60,10 +64,8 @@ namespace Avalonia.Markup.Data.Plugins
var genericTypeParameters = paramTypes . Concat ( new [ ] { returnType } ) . ToArray ( ) ;
PropertyType = Type . GetType ( $"System.Func`{genericTypeParameters.Length}" ) . MakeGenericType ( genericTypeParameters ) ;
}
// TODO: Is this going to leak?
// TODO: Static methods?
Value = method . CreateDelegate ( PropertyType , reference . Target ) ;
Value = method . IsStatic ? method . CreateDelegate ( PropertyType ) : method . CreateDelegate ( PropertyType , reference . Target ) ;
}
public override Type PropertyType { get ; }
@ -73,19 +75,18 @@ namespace Avalonia.Markup.Data.Plugins
public override bool SetValue ( object value , BindingPriority priority ) = > false ;
protected override void SubscribeCore ( IObserver < object > observer )
{
SendCurrentValue ( ) ;
}
private void SendCurrentValue ( )
{
try
{
var value = Value ;
Observer . OnNext ( value ) ;
Observer . OnNext ( Value ) ;
}
catch { }
}
private void SendCurrentValue ( )
{
}
}
}
}