Catel.Fody icon indicating copy to clipboard operation
Catel.Fody copied to clipboard

Method OnPropertyChanged for exposed property is called with old value

Open Green7 opened this issue 1 year ago • 5 comments

  • [x] WPF
  • [ ] UWP
  • [ ] iOS
  • [ ] Android
  • [ ] .NET Standard
  • [x] .NET Core

Component

ViewModel

Version of Library

Catel.MVVM 6.0.0-alpha1271 Catel.Fody 4.9.0

Version of OS(s) listed above with issue

Windows 11

Steps to Reproduce

  1. Create model:
public class AppSettingsModel : ViewModelBase
{
  public string SelectedThemeName { get; set; }
}
  1. Create ViewModel and OnPropertyChangedMethod:
public class AppSettingsViewModel : ViewModelBase
{
    [Model]
    [Expose("SelectedThemeName")]
    public AppSettingsModel AppSettings { get; set; }
   
    public AppSettingsViewModel(AppSettingsModel appSettings)
    {
       AppSettings = appSettings;
    }

    private void OnSelectedThemeNameChanged()
    {
       //  This method is called when AppSettings.SelectedThemeName have old value, not the current one
    }
}
  1. Change property (for example, by binding in the view)

Expected Behavior

OnPropertyChanged should be called after property gets its new value.

Actual Behavior

OnPropertyChanged is called before the property value changes. But if we get the value of property using dynamic object it will be correct. For example:

    private void OnSelectedThemeNameChanged()
    {
      var oldValue = AppSettings.SelectedThemeName; // Old value 
      dynamic thisDynamic = this;
      var theme = thisDynamic.SelectedThemeName;  // Correct value.
    }

Also if we expose property as below:

public class AppSettingsViewModel : ViewModelBase
{
    [Model]
    public AppSettingsModel AppSettings { get; set; }

    [ViewModelToModel("AppSettings")]
    public string SelectedThemeName { get; set; }

OnSelectedThemeNameChanged works correctly and has the current value.

Green7 avatar Oct 03 '23 12:10 Green7

Thanks for reporting and the detailed error report. I will investigate this ASAP. Do you have a repo that I can use? E.g. do you have this code in a public repo?

GeertvanHorrik avatar Oct 04 '23 08:10 GeertvanHorrik

@Green7 I have written a unit test, but cannot reproduce. Can you double check the unit test is correct?

  • https://github.com/Catel/Catel.Fody/blob/develop/src/Catel.Fody.TestAssembly.Shared/Bugs/GH0511.cs
  • https://github.com/Catel/Catel.Fody/blob/develop/src/Catel.Fody.Tests.Shared/Repros/GH0511.cs

GeertvanHorrik avatar Dec 30 '23 12:12 GeertvanHorrik

I added an extra check to check both the model and view model values:

https://github.com/Catel/Catel.Fody/blob/feature/511-exposed-changed-notification/src/Catel.Fody.TestAssembly.Shared/Bugs/GH0511.cs#L41

GeertvanHorrik avatar Dec 30 '23 12:12 GeertvanHorrik

the problem occurs if the variable is bound in UI. I used the code: <TextBox Text="{Binding SelectedThemeName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

In such a situation, OnSelectedThemeNameChanged is called with the old value of AppSettings.SelectedThemeName. But surprisingly, if we use the dynamic object (as in the example), it will show the new, correct value.

Green7 avatar Dec 30 '23 14:12 Green7

Then it's probably the RaisePropertyChanged, I will try to reproduce this inside a unit test.

GeertvanHorrik avatar Dec 30 '23 15:12 GeertvanHorrik