2010-06-10 2 views
0

Я использую команду делегата. Я заметил, что, несмотря на то, что CanExecute является истинным, или false, вызов всегда вызывается. Правильно ли это? Я бы предположил, что Execute вызывается только в том случае, если CanExecute истинно.Выполнение всегда вызывается, даже если CanExecute является ложным, это правильно?

Не могли бы вы уточнить?

спасибо

EDITED тест показывает, что Сохранить всегда называется

   [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; } 
       } 
      } 
+0

Какую версию команды делегата вы используете? Всегда можно вызывать Execute напрямую - только по соглашению WPF-структура воздерживается от него. Как вы используете эту команду? Некоторая дополнительная информация наверняка поможет :). – Goblin

+0

см. Мой отредактированный вопрос – user9969

ответ

1

Ваши методы испытаний не испытывать то, что WPF будет делать во время выполнения.

WPF сначала определит, проверяет ли CanExecute значение true - если это не так, кнопка/MenuItem/InputBinding и т. Д. Отключена и, следовательно, не может быть запущена.

Как я упоминал в своем комментарии, это соблюдается только конвенцией.

+0

«Только по конвенции». Я вижу. Ранние дни в мире wpf. Позвольте мне быть ясным. Если я положил некоторую валидацию в CanExecute и вернусь к false во время выполнения, Execute будет называться stmm.mmmm - это то, что вы говорите? – user9969

+0

Да, если вы вызовете Execute() вручную, ваш код будет срабатывать - WPF не будет вызывать Execute из Button (любой класс, наследующий из CommandBase), если CanExecute команды оценивается как false. Команда делегата не ожидает этого (она ожидает, что значение CanExecute будет равно true. Конечно, вы можете изменить это поведение в своей собственной версии команды делегата, но текущая команда делегата ведет себя так, как вы ожидали бы от ICommand в WPF. – Goblin