lukaszn
lukaszn

Reputation: 83

Fody PropertyChanged setter logic

Is there a way in Fody (MvvmCross app) to change this:

private double _subTotal;

public double SubTotal
{
    get => _subTotal;
    set
    {
        _subTotal = value;
        Recalculate();
    }
}

into something more elegant like:

[AlsoNotifyFor("Recalculate")]
public double SubTotal { get; set; }

How to intercept and call Recalculate() method after PropertyChanged has raised ?

Upvotes: 2

Views: 734

Answers (2)

Not sure if it good solution, but you can use MrAdvice It allo add decorators to property setter. I tested it a little, and it's works.

public class Person : INotifyPropertyChanged {
public string GivenNames { get; set; }

[ SetWrapper( nameof(SomeTest), nameof(SomeTest1) ) ]
public string FamilyName { get; set; }

public string FullName => $"{GivenNames} {FamilyName}";

private void SomeTest( ) {
    Console.WriteLine( nameof(SomeTest) );
}

private static void SomeTest1( ) {
    Console.WriteLine( nameof(SomeTest1) );
}

public event PropertyChangedEventHandler PropertyChanged;

}

and implementation for SetWrapper attribute

public class SetWrapper : Attribute, IMethodAdvice {
private readonly string[] _addingMetod;

public SetWrapper( params string[] addingMethods ) {
    _addingMetod = addingMethods;
}

public void Advise( MethodAdviceContext context ) {
    context.Proceed( );
    foreach( var methodName in this._addingMetod ) {
        InvokeMethod( context, methodName );
    }
    // do other things here
}

private static void InvokeMethod( MethodAdviceContext context, string methodName ) {
    if( context.TargetMethod.Name.StartsWith( "set_" ) && !string.IsNullOrEmpty( methodName ) ) {
        var method = context.TargetMethod?.ReflectedType?.GetMethod( methodName
                                                                   , BindingFlags.Public
                                                                   | BindingFlags.Static
                                                                   | BindingFlags.NonPublic
                                                                   | BindingFlags.Instance );
        if( method != null ) {
            if( method.IsStatic ) {
                method.Invoke( null, Array.Empty<object>( ) );
            } else {
                method.Invoke( context.Target, Array.Empty<object>( ) );
            }
        }
    }
}}

Upvotes: 1

Bartosz
Bartosz

Reputation: 4786

No, it's not - at least not today. What you're looking for (and I also looked for that!) is an ability to add a method to be executed after a property change event has been called, but the attributes don't allow that.

However, you can still use Fody and simply use your code as in the example - Fody will add the OnPropertyChanged() to this and other properties normally.

Upvotes: 0

Related Questions