2012-02-18 1 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何が起こる

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); 
    } 
} 

がある

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

子のviewmodelは、CanRefreshが呼び出されることはありません。コマンドはうまく動作しますが、それは1つのAddItems(それはそれぞれの子ビューモデルで異なる方法で実装された仮想メソッドです)または他のものですが、CanExecuteは決して上がらないようです。私はMVVM Lightツールキットを使用しています。 ありがとう!

+0

「CanRefreshが呼び出されることはありません」と言うときは、CanRefreshプロパティまたはその中のラムダを意味しますか?それは決して呼び出されないことをどのように伝えることができますか? –

答えて

0

LoadedCommandPivotChangedCommanプロパティを呼び出すたびに、新しいリレーコマンドを作成しています。 SL/WPFではこれらのプロパティを頻繁に呼び出すため、プロパティが呼び出されるたびにコマンドを作成しないようにする必要があります。実際にはRefreshResultsCommandが正しいパターンを実装しています。

プロパティ/コマンドを正しく実装するための最良の方法は、Laurent's MVVM snippetsです。スニペットディレクトリにダウンロードして使用してください。常に同じ定型文を生成して品質を向上させるだけでなく、もかなりスピードアップします!

use the installerでもスニペットをインストールできます。

1

私はRelayCommandCanExecuteChangedイベントはビュー層が現在バインドされているビューモデルオブジェクトに発砲しないさんのでCanExecuteメソッドが呼び出されることはありませんされていると思われます。ほとんどのプロパティーアクセスでコマンドを作成しているので、たくさんのコマンドがあります。まだビューレイヤーにバインドされていないコマンドでもイベントを発生させる可能性もあります。より長い。

プロパティgetterが呼び出されるたびに新しいコマンドを作成する人はいなかった。代わりに、すべてのプロパティの代わりにコンストラクタでコマンドを作成してみてください。

+0

コードサンプルを見て、私はそのメソッドを呼び出しています..... –

+0

@DanielPerez:あなたは本当に 'RaiseCanExecuteChanged'メソッドを呼び出しています。それを気付かなかったのは残念です。しかし、それはよく隠されていた。私は私の答えを更新しました。 –

関連する問題