查找与WPF和MVVM / MVVMLight

时间:2016-07-26 00:29:16

标签: wpf mvvm mvvm-light

我是否有一种聪明的方法可以找出WPF Window与ViewModel相关联的内容?

我目前正在构建对话服务,我需要将所有者设置为特定窗口。我目前正在将.Owner属性硬编码为Application.Current.MainWindow,但我想我会在这里查看是否有人做过类似的事情并且很聪明地做到了这一点。

一种方法是,在初始化时使用ViewModel作为我的ViewModelLocator中的键,将Window类型与字典中的ViewModel相关联?那么呢?

假设我的MainViewModel调用以下代码

_dialogService.ShowDialog(settingsWindowViewModel);

我想传递SettingsWindowViewModel的一个属性:

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

并且在DialogService的定义中,ShowDialog将被定义为:

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

GetWindowByViewModel将访问包含Window类型的字典,但我不确定如何获取实际窗口,因为我只有&#39;类型&#39;。< / p>

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

其中owner是与特定Window类型关联的ViewModel。

我在使用Unity的项目中看到了与上述内容类似的内容,但a)我无法回想起我在哪里看到的内容,以及b)我正在使用MVVMLight而不是Unity

有关处理此类情况的任何建议吗?

1 个答案:

答案 0 :(得分:0)

我最后提出了自己的建议。

以下是细分:

  1. 将一个Dictionary of Dictionary添加到ViewModelLocator以存储ViewModel类型和Window Type。

    function _login(username, password){
            var data = {
                username: username,
                password: password
            };
            return $http({
                method: 'POST',
                url: '/api/login/',
                data: data
            });
        };
    

    注意:通过在ViewModelLocator类中定义公共静态字段,确保ViewModelLocator可用于整个应用程序。

    public static ViewModelLocator Instance =&gt; Application.Current.Resources [&#34; Locator&#34;]作为ViewModelLocator;

  2. 将Window类型和ViewModel类型添加到上面定义的WindowsTypes字典中,这些窗口需要显示一个对话框,并且需要充当父窗口。

    public static Dictionary<Type, Type> WindowTypes;
    

    注意:使用&#39; this.DataContext.GetType()&#39;我将在我的场景中工作,因为我在XAML中定义了所有的ViewModel:

    public MainWindow()
    {
        InitializeComponent();
        this.Loaded += (s, e) =>
        {
            // register window type to corresponding viewmodel
            ViewModelLocator.WindowTypes.Add(this.DataContext.GetType(), 
            typeof(this.GetType());
        };
    }
    
  3. 最后,还有DialogService定义:

    DataContext="{Binding Source={StaticResource Locator},
    Path=MainWindowViewModel}"
    
  4. 如您所见,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(); } 参数类型将用于标识在GetWindowByType函数中完成的相关窗口:

    parent

    注意:您可能会注意到failafe,如果它无法在Dictionary中找到相关的ViewModel类型,或者由于某种原因,如果在循环浏览WPF应用程序中所有可用的Windows时相关窗口失败,它将返回Main窗口。

    希望这有帮助。