I've looked at some examples of implementing ICommand and to me the following way is the simplest:
class Command : ICommand {
public Func<object, bool> CanDo { get; set; }
public Action<object> Do { get; set; }
public event EventHandler CanExecuteChanged {
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public Command(Func<object, bool> CanDo, Action<object> Do) {
this.CanDo = CanDo;
this.Do = Do;
}
public bool CanExecute(object parameter) => CanDo(parameter);
public void Execute(object parameter) => Do(parameter);
}
and that's how I've implemented in my test app. In addition to the Command class I've the following class:
class Person : INotifyPropertyChanged {
string firstName, lastName, enabled;
public string FirstName {
get => firstName;
set { firstName = value; Changed();}
}
public string LastName {
get => lastName;
set { lastName = value; Changed(); }
}
public string Enabled {
get => enabled;
set { enabled = value; Changed(); }
}
public Command MyCommand { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
public Person() {
MyCommand = new Command(CanDo, Do);
}
void Changed(string name = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
bool CanDo(object para) {
if (FirstName == "test" && LastName == "test") {
Enabled = "true";
//Changed("Enabled");
return true;
}
else {
Enabled = "false";
//Changed("Enabled");
return false;
}
}
void Do(object para) {
FirstName = "first";
LastName = "last";
}
}
and in xaml I've these:
<Window ...>
<Window.Resources>
<local:Person x:Key="person"/>
</Window.Resources>
<Grid DataContext="{StaticResource person}">
<StackPanel>
<TextBox Text="{Binding FirstName}"/>
<TextBox Text="{Binding LastName}"/>
<TextBlock Text="{Binding FirstName}"/>
<TextBlock Text="{Binding LastName}"/>
<Button Content="Click" Command="{Binding Path=MyCommand}"/>
<Label Content="{Binding Enabled}"/>
</StackPanel>
</Grid>
</Window>
After launching the app, whatever I try to type in those TextBox gets deleted instantly if I call Changed() in the setter of Enabled. If I comment out the Changed() in setter and uncomment two Changed("Enabled") in bool CanDo(object para) it works as expected!
Shouldn't calling the Changed() once in setter be equivalent to those two Changed("Enabled") call in bool CanDo(object para)?