2012-04-13 5 views
2

MVVMモデルを初めて使用しています。私はボタンの数を持つユーザーコントロールを持っています。私は、これらのボタンのClickイベントを、RoutedEventを通じてビューモデルクラスで処理しています。ボタンのクリックイベントで別のユーザーコントロールを呼び出したり開く必要があります。これを達成する方法は?Silverlightのユーザーコントロールのビューモデルクラスから別のユーザーコントロールを開く方法は?

事前のおかげで...

+0

イベントをキャッチしているクラスのすべてのユーザーコントロールにアクセスできませんか? – Stainedart

+0

@CarlT。はい、私はユーザーコントロールのインスタンスを作成できます。しかし、どのようにそれらを表示するには? – Amit

答えて

0

あなたが崩壊に設定visibilityプロパティをXAMLでコントロールを配置し、イベントハンドラで使用すると、C#の

から、目に見える

<TextBlock HorizontalAlignment="Left" Visibility="Collapsed" Name="ErrorBlock" Text="Authentication Failed." VerticalAlignment="Top" Foreground="Red" FontWeight="Bold" /> 

を変更しますか

ErrorBlock.Visibility = System.Windows.Visibility.Visible; 

もう1つの方法は、コントロールをプログラムで作成して親に追加することです(グリッドなど)。次のリンクを参照して、長方形を追加するサンプルをナビゲーション - あなたが記述何グリッド

http://forums.silverlight.net/t/135977.aspx/1

3

はMVVMに新しいほとんどの人が苦労して問題の一つです。私は、自分のビュー(ViewModelはかなりビューに頼らないと思われる)や他のビューでも、自分のViewModelsに何も知識を持たせることを避けるようにしています。

これを解決する1つの方法は、アプリケーション内にすべてのナビゲーションを処理する中央コンポーネントを用意することです。それをNavigationControllerと呼ぶことにしましょう。このコンポーネントは、ナビゲーション要求を処理し、(関連するのviewmodelsとオプション)とそれらの初期化をビューを作成する責任があり、それは本当に様々なのviewmodelsとそれぞれのビュー間の相互依存関係について知っているアプリケーションにおける唯一のコンポーネントです。

ViewModelとコントローラ間の通信は、疎結合ナビゲーション(およびそれ以上)の実装を容易にするイベントアグリゲータ(たとえばTinyMessenger)によって実行されるのが理想的です。私はあなたが簡単なユーザーコントロールではなく、子ウィンドウでホストされているユーザーコントロールを意味し、ダイアログのいくつかの種類を育てたいということを意味していることを疑う最終発言として

。これは私が概説したアプローチを使用して解決することができます。

0

あなたがしたいことをするには、コントロールとフォームの組み合わせを使用したいと思うでしょう。私の答えはSilverlight 4以降に適用されます。 まず最初に、私はボタン "コマンド"をビューモデルのコマンド実装にバインドします。次の例では、私のコントロールのDataContextは、私のビューモデルのインスタンスです。私のViewModelは、一連のキー(文字列)とViewModelCommandクラスのハッシュテーブルを実装しています。実装の複雑さを無視する。ボタンは、上記の例で

<Button Style="{StaticResource stTitleButton}" Height="Auto" Foreground="White" 
        Command="{Binding ViewModelCommandIoC.ViewModelCommands[FIND]}" 
        CommandParameter="{Binding ElementName=enHiddenControl}" 
        Visibility="{Binding CanSwitchCustomer,Converter={StaticResource VisibilityValueConverter},FallbackValue=Collapsed}" 
        > 

「COMMAND」に囲まれているポイントは、コマンドが「FIND」の下にインデックスを付け、私のコマンドにバインドされています。これはコマンドに直接バインドするのと同じです。次の重要な部分はCommandParameterです。これは、新しいウィンドウで表示したいコントロールの隠れたインスタンスです。この場合のコントロールの名前は「enHiddenControl」です。このコントロールを画面のどこにでも置くことができます。隠されていることを確認してください。これは、コマンドのメソッドシグネチャのパラメータとして使用されます。例えば:この送信者が来ると

/// <summary> 
    /// Finding an existing customer 
    /// </summary> 
    /// <param name="sender">The command parameter - control </param> 
    /// <param name="e"></param> 
    public void OnChangeCustomer(object sender)... 

、目標は、型を取得し、そのクラスのインスタンスを作成するためにアクチベーターを使用することです。アクティベータはSystem.ReflectionまたはSystem.Reflection.Emitにあります。 (私は私の頭の上からこれを入力することだし、それは主に理論的ですが、動作するはずです;)

Activator.CreateInstance(sender.GetType()) 

あなたは、このクラスのインスタンスを作成したら、「ChildControl」にLayoutGridに追加します。どうやって?グリッドを作成し、 "LayoutRoot"という名前を付けます。 ChildControlを作成し、子コントロールにグリッドを追加して、作成したインスタンスをグリッドに追加します。フォームを表示します。理論的には、特定のクラスについて知らなくても、コントロールでフォームを動的に作成しただけです。ジェネリック薬のみ。フォームのサイジングは、別の話です。私は幅と高さの両方にAutoを使用します。その結果、コントロールのサイズは、理論的にフォームのサイズを決定するはずです。このすべては、私はこれらのスタントを引っ張ってきた時間の量を考えると、理論的で、テストされていなかったが、それが動作するはず

public void OnChangeCustomer(object sender) 
{ 
     //the search screen 
     if (sender is UserControl) 
     { 
      UserControl uc = Activator.CreateInstance(sender.GetType()) as UserControl; 
      Grid grdLayoutRoot = new Grid(); 
      grdLayoutRoot.Name = "LayoutRoot"; 
      grdLayoutRoot.Children.Add(uc); 
      ChildWindow cw = new ChildWindow(); 
      cw.Content = grdLayoutRoot; 
      cw.Show(); 
     } 
} 

終わりにする方法は次のようになります。 C#の自然の一種。

関連する問題