My "parent" view-model (AnalyzeVm
) has a child view-model (ScanVm
) that represents something that can be saved to disk. I want to give the parent a command (SaveCmd
) that is enabled only when the ScanVm.IsDirty
property is true.
I already use DelegateCommand
and its ObservesProperty
functions all over the place so I tried to use it for this. But in this one case I cannot get the ObservesProperty
expression to trigger a call to CanExecute
.
The difference here (from all the other places I use ObservesProperty
that work fine) is that I'm monitoring a property of the child object. Not of my own
I need to understand why this is not working. I thought this was a valid thing to do.
Here are the two view models (stripped down for clarity)
// Parent view-model. Derives from a class that implements INotifyPropertyChanged.
public class AnalyzeVm : BaseViewModel
{
private ScanVm _scan;
public AnalyzeVm(ScanVm scan)
{
_scan = scan;
// Set up the command. Try to make it monitor a property of the ScanVm
// object instead of one of our own.
SaveScanCmd = new DelegateCommand(
() => { _scan.Save() } // execute -- saves the scan
() => { return _scan.IsDirty; }) // only valid when scan is dirty
.ObservesProperty(() => scan.IsDirty); // So observe IsDirty property
// Now just as a sanity check, add a handler for that property changing
// to the PropertyChangedEventManager and log when it does.
PropertyChangedEventManager.AddHandler(
scan,
(_, _) => Debug.WriteLine("IsDirty changed"),
nameof(ScanContext.IsDirty));
}
public ICommand SaveScanCmd { get; }
// other code...
}
// ScanVm class.
public class ScanVm : BaseViewModel
{
private bool _isDirty;
public bool IsDirty
{
get => _isDirty;
set => SetProperty(ref _isDirty, value); // Raises PropertyChanged event
}
public void Save()
{
// Code here to save the ScanVm
IsDirty = false; // No longer dirty
}
// ... other code
}
I am sure that the IsDirty
property is properly changing and firing the event. I confirmed it many times. And I'm already using Observes
property successfully when I observe my own class' properties. For example, I were to, take the SaveCmd
and move it into the ScanVm
class itself -- so that the property expression just observed the ScanVm
's own property, then it works fine. I do that all over the place in my code.
This is the only place I'm trying to observe another object's property. Is it valid to do? if so, what am I doing wrong?
CodePudding user response:
ObservesProperty
primarily works on properties of the containing object
public bool IsDirty {...}
...ObservesProperty( () => IsDirty );
plus nested properties
public ScanVM Child {...}
...ObservesProperty( () => Child.IsDirty );
It just doesn't observe properties on any given instance, because it starts looking from the containing object (AnalyzeVm
in this case).