2016-07-26 1 views
0

ViewModelに関連付けられているWPFウィンドウを知るにはスマートな方法がありますか?WPFとMVVM/MVVMLightでViewModelに関連付けられたウィンドウを検索

私は現在ダイアログサービスを構築しており、所有者を特定のウィンドウに設定する必要があります。私は現在.OwnerプロパティをApplication.Current.MainWindowにハードコーディングしていますが、私は誰かがこれに似た何かをしてこれをやっているかどうかを調べるためにここをチェックすると思っていました。

Windowタイプを辞書のViewModelに関連付けるには、初期化時にViewModelをキーとしてViewModelLocatorを使用しますか?しかし、それでは?

SettingsWindowViewModel settingsWindowViewModel = new SettingsWindowViewModel 
{ 
    Title = "Settings", 
    Owner = "MainViewModel" or //this; 
} 

とDialogServiceの定義では、ShowDialogを:私のMainViewModelを想定し

は私のような私のSettingsWindowViewModelの特性の一つを渡したいと思い、次のコード

_dialogService.ShowDialog(settingsWindowViewModel); 

を呼び出しますそのように定義される:

public bool? ShowDialog(IDialogWindowViewModel dialogViewModel) 
{ 
    var win = new WindowDialog 
    { 
     Title = dialogViewModel.Title, 
     Owner = GetWindowByViewModel(dialogViewModel.Owner); 
    } 
} 

GetWindowByViewModelは、ウィンドウタイプを含む辞書にアクセスしますが、実際のウィンドウを取得する方法はわかりません。なぜなら、 'タイプ'しかないからです。

return App.Locator.ViewModelLocator.GetWindowByViewModel(owner); 

ここで、ownerは、特定のウィンドウタイプに関連付けられたViewModelです。

私はUnityを使用していたプロジェクトで上記のようなものを見てきましたが、私はこれを見たところ、A)私は思い出すことができないと、b)私はUnityではなくMVVMLightを使用しています。

このようなシナリオを処理するための提案はありますか?

答えて

0

私は自分自身の提案と一緒に行きました。

ここ内訳です:

  1. はViewModelにタイプとウィンドウタイプを格納するViewModelLocatorへの辞書を追加します。

    public static Dictionary<Type, Type> WindowTypes; 
    

    注:ViewModelLocatorはViewModelLocatorクラスのパブリック静的フィールドを定義することによって、全体のアプリで利用可能であることを確認してください。

    public static ViewModelLocatorインスタンス=> Application.Current.Resources ["Locator"] ViewModelLocator;

  2. ダイアログボックスを表示するために必要になりますし、それは親ウィンドウとして機能する必要があります任意のウィンドウに上記で定義されたWindowsTypes辞書にウィンドウタイプとのViewModelタイプを追加します。

    public MainWindow() 
    { 
        InitializeComponent(); 
        this.Loaded += (s, e) => 
        { 
         // register window type to corresponding viewmodel 
         ViewModelLocator.WindowTypes.Add(this.DataContext.GetType(), 
         typeof(this.GetType()); 
        }; 
    } 
    

    注: 'this.DataContext'の使用。私は、XAMLですべての私のviewmodelsを定義していてメソッドGetType()は」いつも私のシナリオで動作します:

    DataContext="{Binding Source={StaticResource Locator}, 
    Path=MainWindowViewModel}" 
    
  3. 最後に、DialogService定義があります:あなたが見ることができるように

    public bool? ShowDialog(IDialogWindowViewModel dialogViewModel, object parent) 
    { 
        var win = new WindowDialog 
        { 
         Title = dialogViewModel.Title, 
         BtnAccept = {Content = dialogViewModel.AcceptButtonText, 
         Command = dialogViewModel.AcceptButtonCommand}, 
         BtnCancel = {Content = dialogViewModel.CancelButtonText, 
         Command = dialogViewModel.CancelButtonCommand}, 
         SizeToContent = dialogViewModel.SizeToContent, 
         Width = dialogViewModel.Width, 
         Height = dialogViewModel.Height, 
         WindowStartupLocation = dialogViewModel.WindowStartupLocation, 
         DataContext = dialogViewModel, 
         Owner = GetWindowByType(parent.GetType()) 
        }; 
        return win.ShowDialog(); 
    } 
    

は、

private Window GetWindowByType(Type type) 
{ 
    if (ViewModelLocator.WindowTypes.ContainsKey(type)) 
    { 
     return Application.Current.Windows.Cast<Window>().FirstOrDefault 
     (window => window.GetType() == ViewModelLocator.WindowTypes 
     [type]) ?? App.Current.MainWindow; 
    } 
    else 
    { 
     return App.Current.MainWindow; 
    } 
} 
で行われる関連するウィンドウを識別するために、 parentパラメータタイプが使用されます。

注意:フェールセーフに気付くかもしれません。もし、関連するViewModel型が辞書に見つからなかった場合、または何らかの理由でWPFアプリケーションで使用可能なすべてのWindowsをループするときに関連するウィンドウに失敗した場合は、 。

これが役に立ちます。

関連する問題