2011-07-07 207 views
1

私はContentControl内でユーザコントロールをロードする親ウィンドウを持っています。親ウィンドウには、ツールバーにいくつかのボタン(保存ボタン)があります。私はこれらのボタンを割り当てて、usercontrolの内部で処理されるようにしたいと思います。親ウィンドウのイベントをMVVMのUserControl内部ハンドラにバインド

私は自分のICommandコマンドをusercontrolのViewModelから管理する必要があります。要約すると:ユーザーが情報を保存するためにuserControlが処理するイベントを発生させるために、(メインウィンドウ上の)「保存」ボタンをクリックします。コントロール内。

これは可能ですか?

答えて

0

しばらくしてからこの質問に戻ります。私は私の親ウィンドウと通信する必要があったので、私は親ビューウィンドウを親ウィンドウから右にバインドするようにしました。主に子ビューモデルをその親から起動されたイベントにアタッチして、子コントロールの外部にメッセージを表示します。

MVVMパターンを完全に使用していない可能性がありますが、これらの機能をより詳細に制御したいと考えていました。

2

これには2通りの方法があります。 MVVMを使用して


  1. あなたの窓は、ユーザーコントロールが含まれているので、あなたは(と仮定し、それがUserControlViewModelと呼ばれている)ので、そのウィンドウがユーザーコントロールのViewModelへの参照を持って設定する必要があります。あなたはUserControlViewModelでコマンドを使用している場合、あなたは、そのコマンドにバインド呼び出すことによってできます。UserControlViewModel.Command何かのように:

    <Button x:Name="Save" Content="Save" Command="{Binding UserControlViewModel.SaveCommand}"> 
    
  2. 使用イベントハンドラ

    繰り返しになりますが、あなたの窓は、参照を持っている必要がありますイベントハンドラが実装されているクラスに追加します。あなたのウィンドウのXAMLファイルに次のように持つことができ:

    <Button x:Name="Save" Content="Save" Clicked="SaveButtonClicked"/> 
    

    その後の後ろにあなたのコードでは、

      private void SaveButtonClicked(.... sender, .... e) 
          { 
           UserControlClass.SaveData(); 
           // or using command 
           UserControlClass.MyCommand.Execute() 
          } 
    
+0

こんにちは@seekle、私は明示的にユーザーコントロールを宣言していない場合は、代わりに、それらを読み込み、ViewModelでContentControlを使用します。どのようにして、ジェネリックの親が「ある種の」viewModelがそのイベントをリスンしていることを「知っている」ようにすることができますか?ありがとうございます –

1

をOK、あなたは親ウィンドウに子要素のコマンドをバインドしようとしています。まずusercontrolに名前を付け(たとえばx:Name = MyUserControl)、ユーザーコントロールのdatacontext/viewmodel(たとえばICommand MyCommand)にパブリックコマンドを書き込みます。 Now]ボタンでこの

<Button x:Name="SaveButton" Command={Binding ElementName=MyUserControl, Path=DataContext.MyCommand} /> 

これは、ボタンが子ユーザーコントロールのDataContextの内のコマンドにコマンド:)ところで

、あなたの周り(すなわち結合子、他の方法を探している場合は、保存的に結合されますかmvvmで親にコマンド)、FindAncestorを使う必要があります。 codeproject article これについては次のように見てください。

+0

ありがとう@あなたのコードとリンクのための許可。私がしたいことは、いくつかのボタンを持つラッパーを持っていると私は望むすべてのusercontrolをロードしますが、すべてのusercontrolは私のラッパーをクリックしたイベントに応答する必要があります。私はより一般的な方法でそれを行うことができますか?または、私はこれをやって間違っていますか? –

+0

@Rodrigo Caballero:私がこれを行うと考えることができる最良の方法は[CompositeCommand](http://msdn.microsoft.com/en-us/library/microsoft.practices.prism.commands.compositecommand%28v=pandp.38です。 %29.aspx)。 [Prism doc](http://compositewpf.codeplex.com/releases/view/55580)をダウンロードし、第6章を参照してください。これでアイデアが得られます。その後、Prismのコードをダウンロードして独自の方法で実装できます:) – Amit

0

これは、ルーティングコマンドが機能する場合のようです。ルーテッドコマンドの場合、トールバーボタンのコマンドを「保存」に設定します。次に、ユーザーコントロールで、「保存」コマンドを待機するコマンドバインディングを追加します。 bindingコマンドのコードビハインドのイベントハンドラで

<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <UserControl.CommandBindings> 
    <CommandBinding 
     Command="Save" 
     CanExecute="SaveCommand_CanExecute" 
     Executed="SaveCommand_Executed" 
    /> 
    </UserControl.CommandBindings> 

</UserControl> 

、ただのviewmodelを見つけて、それののviewmodelにsaveコマンドを呼び出します。より純粋なMVVMアプローチを望むなら、Josh Smith's approach to routed commands with MVVMを試すことができます。

ユーザーコントロールにフォーカスがある限り、保存ボタンの保存コマンドはユーザーコントロールのコマンドバインディングにルーティングし、保存コマンドを実行します。

これは、ContentPresenterの動的に読み込まれたユーザーコントロールからツールバーボタンを切り離すことを目的としていると思います。

+0

実際、このアプローチはそれを解決するでしょう。しかし、あなたはApplicationCommandsの使用について話しています。特定のViewModel上で独自のICommandsを使用したい場合は、それは不可能で、コマンドを静的なプロパティとして置くことも考えられますが、別の方法があると思います。 –

+0

このアプローチでは、UserControlで代行受信できるApplicationCommandsを使用します。いったん傍受されると、自分のICommandをコードで呼び出すことができます。または、Josh Smithのアプローチのようなものを使用して、インターセプトされたappコマンドをVMに直接渡すことができます。 – NathanAW

関連する問題