Я рассмотрел несколько примеров реализации ICommand
, и для меня следующий способ является самым простым:
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);
}
, и именно так я реализовал свое тестовое приложение. В дополнение к классу Command
у меня есть следующий класс:
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";
}
}
и в xaml
у меня есть эти:
<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>
После запуска приложения все, что япопробуйте набрать те TextBox
, которые будут удалены немедленно, если я позвоню Changed()
в setter
из Enabled
. Если я закомментирую Changed()
в setter
и раскомментирую два Changed("Enabled")
в bool CanDo(object para)
, он будет работать как положено!
Не должен ли вызов Changed()
один раз в setter
быть эквивалентным этим двум Changed("Enabled")
вызовам в bool CanDo(object para)
?