2012-02-18 6 views
0

Я пытаюсь создать команду, которая привязывается к кнопке, и зависит от иерархии режимов просмотра для представления точки и сводных элементов в приложении wp7. Это идет что-то вроде этого (я опущу столько шаблонный код, как это возможно):RelayCommand не запускает CanExecute

Родитель ViewModel:

public RelayCommand RefreshCommand 
    { 
     get 
     { 
      return _refreshCommand; 
     } 

     set 
     { 
      if (_refreshCommand == value) 
      { 
       return; 
      } 

      var oldValue = _refreshCommand; 
      _refreshCommand = value; 

      // Update bindings, no broadcast 
      RaisePropertyChanged(RefreshCommandPropertyName); 
     } 
    } 


    public RelayCommand<RoutedEventArgs> LoadedCommand 
    { 
     get 
     { 
      Action<RoutedEventArgs> getCurrentViewmodel = (args) => 
      { 
       CurrentViewModel = SearchByLocationViewModel; // maybe something better... 
       RefreshCommand = CurrentViewModel.RefreshResultsCommand; 
       RefreshCommand.RaiseCanExecuteChanged(); 
      }; 
      return new RelayCommand<RoutedEventArgs>(getCurrentViewmodel); 
     } 
    } 

    public RelayCommand<SelectionChangedEventArgs> PivotItemChangedCommand 
    { 
     get 
     { 
      Action<SelectionChangedEventArgs> pivotChanged = (args) => 
      { 
       if (args != null) 
       { 
        // update current viewmodel 
        CurrentViewModel = ((Microsoft.Phone.Controls.PivotItem) args.AddedItems[0]).DataContext as ISearchViewModelBase; 
        RefreshCommand = CurrentViewModel.RefreshResultsCommand; 
       } 
      }; 
      return new RelayCommand<SelectionChangedEventArgs>(pivotChanged); 
     } 
    } 

Итак, я устанавливаю свойство RefreshCommand вида модели родительской по команде ребенка каждый раз, когда он загружается, и я делаю то же самое при изменении выбранного значения.

Xaml

<Button Command="{Binding RefreshCommand}" /> 

Детский ViewModel

public Func<bool> CanRefresh 
{ 
    get { return() => !IsLoading; } 
} 

private RelayCommand refreshResultsCommand; 

public RelayCommand RefreshResultsCommand 
{ 
    get 
    { 
     Action doRefresh =() => 
     { 
      SearchResults.Clear(); 
      this._pageNumber = 0; 
      AddItems(); 
     }; 
     return refreshResultsCommand = refreshResultsCommand ?? new RelayCommand(doRefresh, CanRefresh); 
    } 
} 

Что происходит, то CanRefresh никогда не вызывается. Команды работают нормально, в зависимости от того, какой пивотитем он вызывает один AddItems (это виртуальный метод, реализованный по-разному в каждой модели просмотра для детей) или другой, но это похоже на то, что CanExecute никогда не поднимается. Я использую инструментарий MVVM Light. Спасибо!

+0

Когда вы говорите «CanRefresh НИКОГДА не звонит», вы имеете в виду свойство CanRefresh или лямбда внутри него? Как вы можете сказать, что его никогда не называют? –

ответ

0

Ну, вы создаете новую команду реле каждый раз, когда вызываете свои LoadedCommand и PivotChangedComman. Поскольку SL/WPF вызывает эти свойства довольно часто, вы должны следовать, чтобы вы не создавали команду каждый раз, когда вызывается свойство. На самом деле ваш RefreshResultsCommand реализует правильный шаблон.

Лучший способ обеспечить правильное выполнение свойств/команд - использовать Laurent's MVVM snippets. Загрузите их в свой каталог фрагментов и просто используйте их. Помимо производства всегда одного и того же кода шаблона и, таким образом, улучшения качества, они также значительно ускорить работу!

Вы также можете установить use the installer, чтобы установить фрагменты.

1

Я подозреваю, что метод CanExecute никогда не называют, потому что CanExecuteChanged событие RelayCommand никогда не увольняют на объект вида-модели, что вид слой в настоящее время привязан. Поскольку вы создаете команды для большинства доступов к свойствам, есть много команд, и вполне возможно, что вы запускаете событие по команде, которая еще не привязана к слою представления или к которой нет дольше.

Я никогда не видел, чтобы кто-либо создавал новые команды каждый раз, когда вызывается свойство getter. Не могли бы вы попытаться создать команды один раз в конструкторе, а не на каждом доступе к ресурсу, и посмотреть, не исправляет ли это что-то?

+0

взгляните на образец кода, i AM, который вызывает этот метод ..... –

+0

@ DanielPerez: вы действительно вызываете метод «RaiseCanExecuteChanged», извините, что не заметили его. Это было хорошо скрыто. Я обновил свой ответ. –