In an application I'm using for control of one or more devices on a serial communication bus, I'm using an IsAlive
property in my DeviceModel
class to tell if the communication link with the device is up (i.e. replies are received on the expected address). The property fires a PropertyChanged
event notification.
I'm using the IsAlive
property both for setting the background color on a data template and for controlling the command predicate for the buttons in the data template. By yanking out the communication cable, I'm forcing the link to time out and set IsAlive
to false. This works fine on the template background color, but the buttons aren't responding on the predicate change until I click anywhere on the View.
Any idea why this is? And how I can get the buttons to update immediately when setting the IsAlive
property?
C# command predicate:
private bool CanPressMovementButton(object obj) {
if (IsAlive == true && Address > -1 && Address < 31) {
return true;
}
return false;
}
Here's a screenshot where the buttons are disabled even though the IsAlive
property is set true
. The buttons are enabled immediatly when I click the View.
After Anton Semenov's tip about using the RaiseCanExecuteChanged
method in Prism's DelegateCommand implementation, it worked like a charm. Setting IsAlive
from the model now updates the View immediately without any need to give focus to the View. Since I'll be supporting several device types with different commands depending on device type, I'm setting the DelegateCommand
objects like this:
public bool IsAlive {
get { return _isAlive; }
set {
bool newValue = SetNotify(ref _isAlive, value);
if (newValue) {
var properties = GetType().GetProperties();
foreach (var property in properties) {
if (property != null && property.PropertyType == typeof(DelegateCommand)) {
var command = (DelegateCommand)property.GetValue(this, null);
command.RaiseCanExecuteChanged();
Console.WriteLine("Raised!");
}
}
}
}
}