2009-08-29 17 views
122

I持って、私は次の標準的な構文を使用して、私のXAMLファイルから実行していますコマンド:私はからの2つの情報を必要とすることを実現するまで結合WPFを使用して、2つのコマンドパラメータを渡す

<Button Content="Zoom" Command="{Binding MyViewModel.ZoomCommand}"/> 

これはうまく働いたがこの操作をユーザーの期待通りに行うためのビュー(キャンバスの幅と高さは具体的には)。

それは私のコマンドの引数として配列を渡すことも可能ですが、私はCommandParameterに私の2つのキャンバスのプロパティへの結合を指定するための方法であることが表示されていないように思え

<Button Content="Zoom" 
     Command="{Binding MyViewModel.ZoomCommand" 
     CommandParameter={Binding ElementName=MyCanvas, Path=Width}"/> 

私のコマンドに幅と高さの両方を渡すにはどうしたらいいですか? XAMLのコマンドを使用してこれを行うことは可能ではないようで、この情報をズームメソッドに渡すには、コードビハインドでクリックハンドラを呼び出す必要があります。

答えて

182

最初に、MVVMを実行している場合、ビューからバインドされた別のプロパティを使用して、通常はこの情報をVMに利用できます。これにより、コマンドにパラメータを渡す必要がなくなります。

しかし、あなたはマルチバインドもでき、パラメータを作成するために、コンバータを使用します。あなたのコンバータでは

<Button Content="Zoom" Command="{Binding MyViewModel.ZoomCommand"> 
    <Button.CommandParameter> 
     <MultiBinding Converter="{StaticResource YourConverter}"> 
      <Binding Path="Width" ElementName="MyCanvas"/> 
      <Binding Path="Height" ElementName="MyCanvas"/> 
     </MultiBinding> 
    </Button.CommandParameter> 
</Button> 

を:

public class YourConverter : IMultiValueConverter 
{ 
    public object Convert(object[] values, ...) 
    { 
     return values.Clone(); 
    } 

    ... 
} 

次に、あなたのコマンドの実行ロジックで:

public void OnExecute(object parameter) 
{ 
    var values = (object[])parameter; 
    var width = (double)values[0]; 
    var height = (double)values[1]; 
} 
+1

は感謝ケント - それは私が探していたまさにでした。あなたの最初のアプローチがより好きで、VMがパラメータを渡す必要がなくてもバインディングを通してビューの「状態」を知ることができますが、まだテストすることができます。できるだけ大きなキャンバスを作成し、この値をVMに渡すためのビューが必要なので、ここで私がここでうまくいくかどうかはわかりません。私はそれをバインドする場合、VMの幅を設定する必要はありませんか?この場合、VMはビューにバインドされていますか? – JasonD

+0

@Jason:どちらにしてもかまいません。つまり、ビュー・プッシュをビュー・モデルに戻して変更したり、ビュー・モデルに変更をビューにプッシュしたりさせます。 TwoWayバインディングはいずれかのオプションを利用できるようになります。 –

+0

私のプログラムでは、OnExecuteメソッドのパラメータはnull値を持つ配列ですが、コンバータの値は予期した通りです –

13

ConverterでTupleを使用し、OnExecuteでパラメータオブジェクトをTupleにキャストします。選択したソリューションのコンバータで

public class YourConverter : IMultiValueConverter 
{  
    public object Convert(object[] values, ...)  
    { 
     Tuple<string, string> tuple = new Tuple<string, string>(
      (string)values[0], (string)values[1]); 
     return (object)tuple; 
    }  
} 

// ... 

public void OnExecute(object parameter) 
{ 
    var param = (Tuple<string, string>) parameter; 
} 
35

、あなたは(values.Cloneを追加する必要があります)それ以外の場合はコマンド終了ヌルのパラメータ

public class YourConverter : IMultiValueConverter 
{ 
    public object Convert(object[] values, ...) 
    { 
     return values.Clone(); 
    } 

    ... 
} 
+2

こんにちは、このクローン()との追加はそれを働かせます:)あなたは何を説明してください、違いがありますか?なぜ私はクローン()が動作する必要があるのか​​分からないのですか?ありがとうございました。 – adminSoftDK

関連する問題