2

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 ?

Eduard Malakhov
  • 1,095
  • 4
  • 13
  • 25
lukaszn
  • 83
  • 1
  • 7
  • I am not sure, what your intent is. AFAIK, `AlsoNotifyFor` instructs `Fody` to notify subscribers that the given property has changed whenever the annotated property changes. So, in your example, whenever `SubTotal ` is changed, two `PropertyChanged` events will be raised - one for `SubTotal ` and the other for `Recalculate` (which is meaningless since there's no such property `Recalculate`). – Eduard Malakhov Mar 18 '18 at 06:58

2 Answers2

1

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>( ) );
            }
        }
    }
}}
0

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.

Bartosz
  • 4,406
  • 7
  • 41
  • 80