C# 即使CanExecute为false,也始终调用Execute,对吗?
我正在使用委托命令。 我注意到,无论CanExecute是真是假,总是调用execute。 这是正确的吗? 我假设只有当CanExecute为true时才会调用Execute 你能澄清一下吗 非常感谢 编辑的测试显示始终调用SaveC# 即使CanExecute为false,也始终调用Execute,对吗?,c#,C#,我正在使用委托命令。 我注意到,无论CanExecute是真是假,总是调用execute。 这是正确的吗? 我假设只有当CanExecute为true时才会调用Execute 你能澄清一下吗 非常感谢 编辑的测试显示始终调用Save [TestFixture] public class Can_test_a_method_has_been_called_via_relay_command {
[TestFixture]
public class Can_test_a_method_has_been_called_via_relay_command
{
[Test]
public void Should_be_able_to_test_that_insert_method_has_been_called_on_repository()
{
var mock = new Mock<IEmployeeRepository>();
var employeeVm = new EmployeeVM(mock.Object) {Age = 19};
employeeVm.SaveCommand.Execute(null);
mock.Verify(e=>e.Insert(It.IsAny<Employee>()));
}
[Test]
public void Should_be_able_to_test_that_insert_method_has_not_been_called_on_repository()
{
var mock = new Mock<IEmployeeRepository>();
var employeeVm = new EmployeeVM(mock.Object) { Age = 15 };
employeeVm.SaveCommand.Execute(null);
mock.Verify(e => e.Insert(It.IsAny<Employee>()),Times.Never());
}
}
public class EmployeeVM:ViewModelBase
{
private readonly IEmployeeRepository _employeeRepository;
public EmployeeVM(IEmployeeRepository employeeRepository)
{
_employeeRepository = employeeRepository;
}
private bool _hasInserted;
public bool HasInserted
{
get { return _hasInserted; }
set
{
_hasInserted = value;
OnPropertyChanged("HasInserted");
}
}
private int _age;
public int Age
{
get { return _age; }
set
{
_age = value;
OnPropertyChanged("Age");
}
}
private string _name;
public string Name
{
get { return _name; }
set
{
_name = value;
OnPropertyChanged("Name");
}
}
private RelayCommand _saveCommand;
public ICommand SaveCommand
{
get
{
return _saveCommand ?? (_saveCommand = new RelayCommand(x => Save(), x => CanSave));
}
}
private bool CanSave
{
get
{
return Age > 18;
}
}
private void Save()
{
Insert();
HasInserted = true;
}
private void Insert()
{
_employeeRepository.Insert(new Employee{Age = Age,Name = Name});
}
}
public interface IEmployeeRepository
{
void Insert(Employee employee);
}
public class Employee
{
public string Name { get; set; }
public int Age { get; set; }
}
}
[TestFixture]
公共类Can_test_方法已通过_relay_命令_调用
{
[测试]
public void应该能够测试插入方法是否已在存储库()上调用
{
var mock=new mock();
var employeeVm=newemployeevm(mock.Object){Age=19};
employeeVm.SaveCommand.Execute(null);
mock.Verify(e=>e.Insert(It.IsAny());
}
[测试]
public void应该能够在存储库()上测试插入方法是否被调用
{
var mock=new mock();
var employeeVm=newemployeevm(mock.Object){Age=15};
employeeVm.SaveCommand.Execute(null);
mock.Verify(e=>e.Insert(It.IsAny()),Times.Never());
}
}
公共类EmployeeVM:ViewModelBase
{
私人只读雇员储蓄库(U employeeRepository);;
公共雇员VM(IEEmployeeRepository雇员住所)
{
_employeeRepository=employeeRepository;
}
已插入私人布尔;
公共图书馆
{
获取{return\u hasserted;}
设置
{
_hasInserted=值;
OnPropertyChanged(“已插入”);
}
}
私人互联网;
公共信息
{
获取{return\u age;}
设置
{
_年龄=价值;
不动产变更(“年龄”);
}
}
私有字符串\u名称;
公共字符串名
{
获取{return\u name;}
设置
{
_名称=值;
不动产变更(“名称”);
}
}
专用中继命令_saveCommand;
公共ICommand SaveCommand
{
得到
{
返回_saveCommand??(_saveCommand=newrelaycommand(x=>Save(),x=>CanSave));
}
}
私人布尔坎萨弗酒店
{
得到
{
返回年龄>18岁;
}
}
私有void Save()
{
插入();
HasInserted=true;
}
专用空白插入()
{
_Insert(新员工{Age=Age,Name=Name});
}
}
公共接口IEmployeeRepository
{
无效插入(员工);
}
公营雇员
{
公共字符串名称{get;set;}
公共整数{get;set;}
}
}
您的测试方法不是测试WPF在运行时将要做什么
WPF将首先确定CanExecute的计算结果是否为true—如果不是,则按钮/MenuItem/InputBinding等被禁用,因此无法启动
正如我在评论中提到的,这只是按照惯例执行的。您使用哪个版本的委托命令?直接调用Execute总是可能的——只有按照约定,WPF框架才会禁止它。如何使用该命令?更多的信息肯定会有帮助:)“只按惯例”。我明白了。wpf世界的早期。让我说清楚。如果我在CanExecute中进行一些验证,并在运行时返回false,则会调用Execute stll。mmmm这是您要说的吗?是的,如果手动调用Execute(),则代码将触发-如果命令的CanExecute计算结果为false,WPF将不会从按钮(从CommandBase继承的任何类)调用Execute。delegate命令不希望出现这种情况(它希望CanExecute的计算结果为true)。当然,您可以在自己版本的delegate命令中自由更改这种行为,但当前的delegate命令的行为与您在WPF中预期的ICommand类似。