WPFアプリケーションでMVVM Lightツールキットを使用しています。既存のウィンドウから新しいウィンドウを開くための最良の方法は何ですか。このMainViewModel
を取得しました。これは私のアプリケーションのMainWindow
を担当します。 MainView
で、ボタンをクリックすると、その上に2番目のウィンドウを開きます。 RelayCommmand
のButton
にバインドされたCommand
を持っています。 RelayCommand
のメソッドでは、新しいウィンドウオブジェクトを作成し、次のようなShow()
を呼び出すだけです。
var view2 = new view2()
view2.Show()
しかし、ViewModelが新しいview2
オブジェクトの作成を担当するべきではないと思います。私はこの投稿を読みました WPF MVVM VIEW MODELから親を取得 Bugnionはview1
からviewmodel1
にメッセージを渡し、view1
を作成することを提案しています新しいview2
。しかし、メッセージをview1
に渡すことで彼が実際に何を意味するのかわかりません。 view1
はどのようにメッセージを処理する必要がありますか?コードビハインドとは何ですか?
よろしく、Nabeel
ViewModel1からView1にメッセージを渡すことは、 MVVM Light Toolkitのメッセージング機能 を使用することを意味します。
たとえば、ViewModel1にShowView2Commandというコマンドを設定し、ビューを表示するメッセージを送信できます。
public class ViewModel1 : ViewModelBase
{
public RelayCommand ShowView2Command { private set; get; }
public ViewModel1() : base()
{
ShowView2Command = new RelayCommand(ShowView2CommandExecute);
}
public void ShowView2CommandExecute()
{
Messenger.Default.Send(new NotificationMessage("ShowView2"));
}
}
View1は、コードビハインドでメッセージを受信するように登録し、正しいメッセージを受信するとView2を表示します。
public partial class View1 : UserControl
{
public View1()
{
InitializeComponent();
Messenger.Default.Register<NotificationMessage>(this, NotificationMessageReceived);
}
private void NotificationMessageReceived(NotificationMessage msg)
{
if (msg.Notification == "ShowView2")
{
var view2 = new view2();
view2.Show();
}
}
}
なぜこのルートに行くのですか?簡単です。ボタンをtoggleButton、ハイパーリンク、またはその他のボタンのようなコントロールに置き換えた場合、「コードビハインド」を更新する必要はありません-MVVMパターンの基本原則です。新しいtoggleButton(または何でも)で、同じコマンドにバインドすることになります。
たとえば、2つのUIが必要なクライアント向けにプロジェクトを作成しています。1つのUIは、プレゼンテーションの点であらゆる点で根本的に異なります。ナビゲーション用の水平タブと垂直RadPanelBar(アコーディオンを考えてください)。これらのビューは両方とも同じviewModelを指すことができます-ユーザーがビュー1の[作業オーダー]タブをクリックすると、パネルバーの作業オーダーヘッダーで実行されるのと同じ "WorkOrderCommand"が実行されます。
分離コードモデルでは、2つの別個のイベントをコーディングする必要があります。ここでコーディングする必要があるのは1つだけです。
さらに、Blendを使用するデザイナーは、必要なレイアウトを作成できます。フック(EventToCommandコントロール)が適切に配置されている限り、私(開発者)は最終製品がどのように見えるかを気にすることはありませんでした。
疎結合は非常に強力です。
このようにして、いくつかのイベントを作成し、それらをviewに登録し、それらをビューモデルで呼び出し、そのポップアップウィンドウを開く必要があるようにすることができます。
この例のように
_public class Mainclass : MainView
{
public delegate abc RegisterPopUp(abc A);
public RegisterPopUp POpUpEvent ;
public RelayCommand ShowCommand { private set; get; }
public void ShowCommand()
{
ShowCommand("Your parameter");
}
}
_
ビュー内MainView mn=new MainView();
ここでイベントを登録します。thake_mn.POpUpEvent +=
_のように、タブボタンを2回クリックします
また、ポップアップメソッドを登録するポップアップウィンドウを開くためのコード。
ここでポイントを逃さない限り-コードビハインドを使用する場合、button_clickイベントを直接実装して2番目のビューを開くのはなぜですか?
Bugnionが提案していると思われるのは、view1->ボタンクリック->リレーコマンド-> viewmodel1->メッセージ-> view1-> view1.cs->ビュー2を開くことです。
コードビハインドを記述することにより、テスト性を犠牲にすることになりますが、なぜそんなに長い道のりをとるのでしょうか?
汎用インターフェイスを使用して、ビュー固有の機能をサービスに抽象化できます。ビューレイヤーでは、これらのサービスの具体的なインスタンスを提供し、IoCコンテナーと依存性注入手法を使用してビューモデルを構築できます。
あなたの場合、必要なメソッドを持つインターフェイスIWindowManagerまたは類似のものを構築できます。これは、ビューレイヤーで実装できます。最近、ダイアログの動作をビューモデルから抽象化する方法を示す小さなブログ記事を書きました。同様のアプローチは、ナビゲーション、メッセージボックスなどのユーザーインターフェイス関連サービスに使用できます。
このリンクは役に立つかもしれません http://nileshgule.blogspot.com/2011/05/silverlight-use-dialogservice-to.html
多くの人は、view.csファイルでサブスクライブされているビューモデルからイベントを発生させるアプローチを使用し、そこからMessageBoxまたはその他のUI関連アクションが実行されます。個人的には、同じサービスの複数の実装を提供できるため、サービスを注入するアプローチが好きです。簡単な例は、SilverlightおよびWindows Phone 7アプリケーションでのナビゲーションの処理方法です。同じビューモデルを使用できますが、アプリケーションタイプに基づいてナビゲーションサービスの異なる実装を挿入できます。
これにアプローチする最良の方法は、ViewModelからウィンドウを開閉することです。 this リンクが示唆するように、
DialogCloser
クラスを作成しますpublic static class DialogCloser { public static readonly DependencyProperty DialogResultProperty = DependencyProperty.RegisterAttached( "DialogResult"、typeof(bool?)、typeof(DialogCloser)、new PropertyMetadata(DialogResultChanged) ); private static void DialogResultChanged(DependencyObject d、DependencyPropertyChangedEventArgs e) { var window = d as Window; if(window! = null)window.Close(); } public static void SetDialogResult(Window target、bool?value) { target。 SetValue(DialogResultProperty、value); } }
GalaSoft.MvvmLight.ViewModelBase
を継承する追加のメンバーを含むベースViewModelを作成します。完了したら、このビューモデルを他のビューモデルのベースとして使用します。ブール? _closeWindowFlag; public bool? CloseWindowFlag { get {return _closeWindowFlag; } set { _closeWindowFlag = value; RaisePropertyChanged( "CloseWindowFlag"); } } public virtual void CloseWindow(bool?result = true) { Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background、 new Action(()) => { CloseWindowFlag = CloseWindowFlag == null?true:!CloseWindowFlag; })); }
DialogCloser.DialogResult
依存関係プロパティをCloseWindowFlag
プロパティにバインドします。次に、ビューモデルからウィンドウを開く/閉じる/隠すことができます。