2013-08-26 19 views
5

私は2つのビュー(AddClientViewとSuggestedAddressesView)によって参照されるAddClientViewModelを持っています。 AddClientViewはアドレスのフィールドを持つフォームです。フォームには、ジオコーディングを使用して入力したアドレスを検証する検証ボタンがあります。複数のアドレスが返された場合は、SuggestedAddressesViewが開きます。ViewModelのビューを開く/閉じる

AddClientViewModel:

private void ValidateExecute(object obj) 
    { 
     SuggestedAddresses = new ObservableCollection<DBHelper.GeocodeService.GeocodeResult>(GeoCodeTest.SuggestedAddress(FormattedAddress)); 

     .... 

     if (SuggestedAddresses.Count > 0) 
     { 
      var window = new SuggestedAddressesView(this); 
      window.DataContext = this; 
      window.Show(); 
     } 
    } 

をここでAddClientViewModelがViewModelBase

public SuggestedAddressesView(ViewModelBase viewModel) 
    { 
     InitializeComponent(); 
     viewModel.ClosingRequest += (sender, e) => this.Close(); 
    } 

から継承SuggestedAddressesViewコンストラクタは、私が午前、他の問題がされている。ここ

は、私は現在、それをやっていることはどのようですAddClientViewModelからOnClosingRequest()を呼び出すと、AddClientViewとSuggestedAddressesViewの両方が終了します。私は、両方のビューが同じViewModelを参照しているため、これが起こることを知っています。これは私が望む行動ではありません。私は独立していずれかのウィンドウを閉じることができるようにしたいと思います。

ビューをViewModelの適​​切なMVVM構造から開いていますが、独立してウィンドウを閉じることができますか?

Command="{Binding CloseWindowCommand, Mode=OneWay}" 
CommandParameter="{Binding ElementName=TestWindow}" 

を使用すると、個々のビューを閉じることができ、これを使用することにより次のようにあなたは、パラメータを送信するよう

答えて

5

、あなたが示唆MVVMガイドラインに違反つもりです。ちょうどそれで、VM内のWindowオブジェクトの作成が間違っていることがわかります。

は、だから今、この整流に: - アプリケーションの中で> 1 VM

  • は、まず1つのビュー<を維持しようとします。より洗練され、同じロジックを持つView実装を非常に簡単に切り替えることができます。 「画期的」でなくても、複数のViewを同じVMに追加するだけで、不器用になります。
  • これで、独自のVMを持つAddClientViewSuggestedAddressesViewが得られました。すばらしいです!

    • 我々はVM(基準を遵守するため)から直接ビューにアクセスすることはできませんので、我々はそのようMessenger(MVVMを使用するなどの方法を使用することができます:VMから閉じるビューのオープン/実装

    ライト)、EventAggregator(PRISM)などを使用して、ビューを開いたり閉じたりして、ビューで実際の操作を行う必要があるときに、VMからビューに「メッセージ」を送信します。

  • このように、VMはメッセージを開始するだけで、同じ操作でユニットテストが正常に行われ、UI要素は参照されません。ビューオープン処理するために「メッセンジャー」のアプローチを使用して

:あなたのロジックを1として

  • は、それがSuggestedAddressesViewをオープンするために依頼する必要がありますAddClientViewModelです。
  • したがって、SuggestedAddresses.Count > 0が検出された場合は、にメッセージを送信し、SuggestedAddressesViewを開くようにメッセージを送信します。AddClientView
  • AddClientView.xaml.csにこのメッセージを受け取った時点で、あなたは現在VM内で行っていることを行います。 SuggestedAddressesViewのオブジェクトを作成し、.Show()を呼び出します。
  • 上記の手順のプロセスで追加する1つの追加ステップは、をSuggestedAddressesViewに割り当て、SuggestedAddressesViewModelとします。

これだけです。今度は、AddClientViewModelが表示されている場合は、SuggestedAddressesViewが表示され、メッセージは自分のビューに送信され、ビューではSuggestedAddressesViewが作成されて表示されます。この方法では、VMはビューを参照せず、MVVMスタンダードを保持します。近くビュー処理するために "メッセンジャー" のアプローチを使用して

  • Viewを閉じるには、非常に単純です。 VMからビューを閉じる必要がある場合は、ビューを閉じるようにメッセージを送信します。
  • このメッセージを受け取ったビューは、.Hide()/.Close()で終了しますが、それ以外の場合は削除してください。

この場合、それぞれのVMは自身のビューの終了を処理し、相互に依存する依存関係はありません。

thisを出発点として、このアプローチの「メッセージ」を扱う際の手引きとなります。 Messengerがどのように動作しているかを見ることができる添付ファイルがあります。これは、MVVM Lightを使用している場合、またはMVVMを実装していない場合、または自分のMVVM実装を使用する場合は、必要なものを手に入れるためのガイドとして使用してください。

ウィンドウを開くためのNavigationService.csクラスを作成します: NavigationService.cs

今そのクラスファイルに次のコードを入れてみましょうViewModelにからウィンドウを開くには

+0

申し訳ありません。 **私は、** SuggestedAddressesView **から収集した情報を** AddClientViewModel **に渡すことを願っています(なぜ2つのビューに1つのVMを使用したのか)。これは、** SuggestedAddressesView **で選択されたアドレスが** AddClientViewModel **で定義されたクライアントに割り当てられているためです。 – francisg3

+1

@ francisg3は私が掲示したリンクの例を見てください。そこに例があると、Modal/Non-Modalが開いた2番目の 'Window'が情報をMainWindowに返します。これは、お客様の要件にも使用するプロセスです。 Messengerを使用してメッセージを送信します(メッセージは、SuggestedAddressViewModelからAddClientViewModelに送信するデータになります) – Viv

0

あなたはRelayCommandを使用することができます。

例:できるだけ早くあなたがVMから(この場合、ビューで)UI要素を参照するよう

public ICommand CloseCommand 
    { 
     get 
     { 
      return new RelayCommand(OnClose, IsEnable); 
     } 
    } 

public void OnClose(object param) 
    { 
     AddClientView/SuggestedAddressesView Obj = param as AddClientView/SuggestedAddressesView; 
     obj.Close(); 
    } 
0

public void ShowWindow1Screen(Window1ViewModel window1ViewModel) 
     { 
      Window1= new Window1(); 
      Window1.DataContext = window1ViewModel; 
      Window1.Owner = Window1View; 
      Window1.ShowDialog(); 
     } 

です。 NavigationService.csクラスのインスタンスを作成するMainWindowViewModelファイル。 次に

Window1ViewModel window1ViewModel = new Vindow1ViewModel(); 
window1ViewModel.Name = MainWindowTextValue; 
NavigationService navigationService = new NavigationService(); 
navigationService.ShowWindow1Screen(window1ViewModel); 
関連する問題