When Using Fody Property Changed and properties changed, Why it does not work?

110 views Asked by At

I have a MVVM Prism Project with DBFirst and Entity Calsses. In View, I used My propertis of model (Class Entities) directly, and because I need to notify every other plcae in project that those properties used, I create a partial class for my Eniety classes and use Fody PropertyChanged in it. but it does not work. here is my Codes:

Entity class:

namespace FodyPropertyChange
{
    public partial class Model
    {
        public int Age { get; set; }
        public string Name { get; set; }
        public string Family { get; set; }
    }
}

my partial entity class:

namespace FodyPropertyChange
{
    [AddINotifyPropertyChangedInterface]
    public partial class Model
    {
        public event PropertyChangedEventHandler PropertyChanged;
    }
}

My View is:

<StackPanel Orientation="Vertical">
    <TextBox Text="{Binding MyModel.Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
    <TextBox Text="{Binding MyModel.Family, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
    <TextBox Text="{Binding MyModel.Age, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
    <Button Content="Test" Command="{Binding TestCommand}" HorizontalAlignment="Center" Width="100" Height="40" Background="Yellow"/>
</StackPanel>

In ViewModel:

public class MainWindowViewModel : BindableBase, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public DelegateCommand TestCommand { get; set; }

    public MainWindowViewModel()
    {
        TestCommand = new DelegateCommand(OnTestCommand, CanExecute);
    }

    private bool CanExecute()
    {
        return (MyModel.Age > 0 && !string.IsNullOrEmpty( MyModel.Name));
    }

    private void OnTestCommand()
    {
        MessageBox.Show("Hi");
    }

    private Model _MyModel = new Model();
    public Model MyModel
    {
        get { return _MyModel; }
        set
        {
            SetProperty(ref _MyModel, value);
            TestCommand.RaiseCanExecuteChanged();
        }
    }
}

and at least in FodyWeavers.xml

<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
  <PropertyChanged />
</Weavers>

as I Describe, It is expected that when Text in Textbox get propper property, CanExecute Fired, but nothing happend. why?

1

There are 1 answers

0
ThomasB On

It seems you have solved your problem, because the repo supplied works as indended and incorporates the cure I just liked to line out.

For others as reference, as similar issues are found elsewhere on SO:

  1. The View is binding to the MyModel.Name sub-Property
  2. The VM (as shown here) is offering the MyModel property and will raise PropertyChange notification when the MyModel property itself will run through the setter
  3. Entering a value, the Binding will set just the Name or Age property of the existing object. Thus it will not go the the MyModel setter but rather to MyModel.Name resp. MyModel.Age setters.
  4. The Model class is not derived from the INotifyPropertyChanged interface, resp. from the ReactiveUI ReactiveObject class, thus the PropertyChanged Fody weaver has no intention to touch the code and add the property change nofication stuff.

When you are using Fody, it is often a good idea to use a tool like the "IlSpy" or "DotPeek" to decompile your assembly and check whether and which code was thrown in by Fody.