2011-06-20 15 views
1

私は、EventTriggerからViewModelにViewModelにパラメータを返すための最良の方法であるという人からのアドバイスに基づいて、InvokeDelegateCommandActionクラスをAlexeyZakharov's weblogから使用しています。InvokeDelegateCommandActionを使用したイベントトリガのCommandParameter

ここに私のものがあります。 ViewModelには

<i:Interaction.Triggers> 
    <i:EventTrigger EventName="SelectionChanged" > 
     <cmnwin:InvokeDelegateCommandAction 
       Command="{Binding SelectedExcludedItemChangedCommand}" 
       CommandParameter="{Binding RelativeSource={RelativeSource self}, Path=SelectedItems}" /> 
    </i:EventTrigger> 
</i:Interaction.Triggers> 

::ビュー(データグリッドが特定されるように)で

public DelegateCommandWithParameter SelectedActiveItemChangedCommand 
{ 
    get 
    { 
     return selectedActiveItemChangedCommand ?? 
      (selectedActiveItemChangedCommand = new DelegateCommandWithParameter(DoSelectedActiveItemsChanged, CanDoSelectedActiveItemsChanged)); 
    } 
} 

public bool CanDoSelectedActiveItemsChanged(object param) 
{ 
    return true; 
} 

public void DoSelectedActiveItemsChanged(object param) 
{ 
    if (param != null && param is List<Object>) 
    { 
     var List = param as List<Object>; 
     MyLocalField = List; 
    } 
} 

私は引数としてオブジェクトを渡すことができますDelegateCommandの新しい種類:

public class DelegateCommandWithParameter : ICommand 
{ 
    #region Private Fields 
    private Func<object, bool> canExecute; 
    private Action<object> executeAction; 
    private bool canExecuteCache; 
    #endregion 

    #region Constructor 
    public DelegateCommandWithParameter(Action<object> executeAction, Func<object, bool> canExecute) 
    { 
     this.executeAction = executeAction; 
     this.canExecute = canExecute; 
    } 
    #endregion 

    #region ICommand Members 
    public bool CanExecute(object parameter) 
    { 
     bool temp = canExecute(parameter); 
     if (canExecuteCache != temp) 
     { 
      canExecuteCache = temp; 
      if (CanExecuteChanged != null) 
      { 
       CanExecuteChanged(this, new EventArgs()); 
      } 
     } 
     return canExecuteCache; 
    } 

    public event EventHandler CanExecuteChanged; 

    public void Execute(object parameter) 
    { 
     executeAction(parameter); 
    } 
    #endregion 
} 

私のコードがDoSelectedActiveItemsChangedになるたびに、argは常にNULLです....私はここに完全なdoofus? CommandParamterはどこにコマンドargsにリンクされますか?なぜ、ビューは何もコマンドに何も返さないのですか?助けてください。

+1

シンプルなボタンとコマンドで同じことを試しましたか?私は私のDataGridの行を削除するためにこれを使用し、それは正常に動作します。多分InvokeDelegateCommandActionは問題を引き起こしますか? – blindmeis

+0

ボタンアクションとInvokeCommandActionで試してみましょう...しかし、これは後ろのViewコードにマップする必要はありませんか?私はここにコードを持たないという要件があります。 – tigerswithguitars

+0

RelayCommandメソッドを実行しようとしましたが、まだバナナはありません。ある時点でボタンメソッドを試してみます。しかし、私はそれが欲しいと思っていることをしていないということにまだ悩まされています/私は何をすべきかわかりません.... – tigerswithguitars

答えて

3

代わりにListBoxとしましたが、同じことがありました。以下は、invokeパラメーターの代わりにCommandParameterを渡すので、問題ありません。だからなぜCommandParameternull

protected override void Invoke(object parameter) { 
    this.InvokeParameter = parameter; 

    if (this.AssociatedObject != null) { 
     ICommand command = this.ResolveCommand(); 
     if ((command != null) && command.CanExecute(this.CommandParameter)) { 
      command.Execute(this.CommandParameter); 
     } 
    } 
} 

CommandParameter は、あなたがnullに設定されて結合するので、適切に動作していないようです。 {RelativeSource Self}InvokeDelegateCommandActionに解決され、SelectedItemsプロパティはありません。代わりに、このバインディングを使用します。

CommandParameter="{Binding RelativeSource={RelativeSource AncestorType={x:Type ListBox}}, Path=SelectedItems}" 

その後CommandParameterListBoxからSelectedItemCollectionに渡します。

すぐに見つかるもう1つの問題があります。 DoSelectedActiveItemsChanged()paramSelectedItemCollectionのインスタンスであり、List<Object>ではありません。

+0

多くのおかげです。私はこのコードをもう少し詳しく見ていたはずです。私がしたように、あなたは決して無条件にこのことを信じてはいけないと思います。ブレークポイントの設定と動作中のデバッグ私は今夜​​それと一緒に行くと、朝に戻って報告します。再び。どうもありがとう。 – tigerswithguitars

+1

'Invoke()'のバグの私の最初のメモが間違っていたので、これを2回書き込む必要がありました。私は、間違った指示がポイントであり、 'EventArgs'ではなく、別のパラメータが渡されるべきであるということをまだ理解していませんでした。 –

1

私はジョエルの観察の助けを借りて問題を解決しました。私は明らかにジョエルに正しい答えを正当なものと信じていますが、質問への編集ではなく答えとしてこの情報を入れるのは正しいと思われます。

私はそうとともにDelegateCommandWithParameter

public ICommand SelectedObjectsChangedCommand 
{ 
    get 
    { 
     return selectedObjectsChangedCommand ?? 
      (selectedObjectsChangedCommand = new DelegateCommand<MyType>(DoSelectedObjectsChangedCommand , CanDoSelectedObjectsChangedCommand)); 
    } 
} 

... SelectionChangedEventArgsのリターンとなりました(メソッドの実行) '行う'

public void DoSelectedObjectsChangedCommand(object param) 
{ 
    if (param != null && param is SelectionChangedEventArgs) 
    { 
     foreach (MyType object in ((SelectionChangedEventArgs)param).AddedItems.Cast<MyType>().ToList()) 
     { 
      selectedObjects.Add(object); 
     } 
     foreach (MyType object in ((SelectionChangedEventArgs)param).RemovedItems.Cast<MyType>().ToList()) 
     { 
      selectedObjects.Remove(object); 
     } 
     UpdateAllCanDos(); 
    } 
} 

を処分した、一般的なDelegateCommandを発見残りのビジネスロジックは非常にスムーズで直感的なUXになります。すべてのアンサーに感謝します。私は1ヶ月間ではなく、NHibernateでWPFとMVVMを行ってきました。私はSOコミュニティが、可能な限り最も豊かな方法で学習曲線を上回っていることを認めています。

+0

ハハハ、私の答えの最初のバージョンで指摘したことは、私の編集ではなく新しいアプローチ( 'SelectionChangedEventArgs'を使用)に近いです。 **:)** –

関連する問題