Prism 5 和 Unity - 使用连接的 ViewModel 手动解析视图

Prism 5 and Unity - Manually resolve View with ViewModel wired up

使用: WPF、Prism 5、Unity

我正在尝试编写我称之为 "WindowDialogService" 的东西,当传递一个类型并调用它时,它将打开一个 Window 以该类型作为内容。我的问题是我无法让 ViewModel 实例化并关联到 View。

我不知道它是否正确,但我在我的视图中使用 AutoWireViewModel 并假设(显然不正确)在使用 Unity 容器解析时 ViewModel 将是 "Located" 即container.TryResolve <T> ()

基本上,我可以解析视图,但视图的 DataContext 为空。

我已经在下面包含了所有相关代码。

查看

<dxc:DXWindow x:Class="ListClassList.Views.AddToClassView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:prism="http://prismlibrary.com/"      
              prism:ViewModelLocator.AutoWireViewModel="True"
              xmlns:dxe="clr-namespace:DevExpress.Xpf.Editors.Settings;assembly=DevExpress.Xpf.Core.v15.2"
              xmlns:dxeditors="http://schemas.devexpress.com/winfx/2008/xaml/editors"
              xmlns:dxc="http://schemas.devexpress.com/winfx/2008/xaml/core" 
              xmlns:dxgt="http://schemas.devexpress.com/winfx/2008/xaml/grid/themekeys"
             xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"              
             xmlns:extToolkit="http://schemas.xceed.com/wpf/xaml/toolkit"
                    WindowStartupLocation="CenterScreen"
                    dxc:ThemeManager.ThemeName="VS2010"
                    Title="{Binding Title}"
                    Width="800"
                    Height="500"
              ResizeMode="CanResizeWithGrip"
             >
    <Grid>
    </Grid>
</dxc:DXWindow>

ViewModel

using MyApp.Data;
using MyApp.Models.Model;
using Prism.Commands;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;

namespace ListClassList.ViewModels
{
    public class AddToClassViewViewModel : BindableBase
    {
        private readonly MyAppDbContext _context;

        private ObservableCollection<MasterClass> _masterClasses;
        public ObservableCollection<MasterClass> MasterClasses
        {
            get { return _masterClasses; }
            set { SetProperty(ref _masterClasses, value); }
        }

        private ObservableCollection<Student> _students;
        public ObservableCollection<Student> Students
        {
            get { return _students; }
            set
            {
                SetProperty(ref _students, value);
            }
        }


        public DelegateCommand FinishCommand { get; set; }


        public AddToClassViewViewModel(IStudentTimetableService studentTimetableService)
        {


        }

    }
}

IWindowDialogService 接口

using System;
using System.Windows;
    namespace MyApp.Infrastructure.Services.Dialogs.WindowDialog
    {
        public interface IWindowDialogService
        {
            bool? ShowDialog<T>(Action onDialogClosed) where T : Window;
        }
    }

Window对话框服务实现

using System;
using System.Collections.Generic;
using System.Windows;
using Microsoft.Practices.ServiceLocation;
using Prism.Unity;


namespace MyApp.Infrastructure.Services.Dialogs.WindowDialog
{
    public sealed class WindowDialogService : IWindowDialogService
    {
        private readonly List<Window> _openWindows = new List<Window>();
        private static volatile WindowDialogService _instance;
        private static readonly object SyncRoot = new Object();

        private WindowDialogService() { }

        public static WindowDialogService Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (SyncRoot)
                    {
                        if (_instance == null)
                            _instance = new WindowDialogService();
                    }
                }
                return _instance;
            }
        }


        public bool? ShowDialog<T>(Action onDialogClosed) where T : Window
        {
            try
            {
                 using (var container = new Microsoft.Practices.Unity.UnityContainer())
                {
                    var dialog = (Window)container.TryResolve <T> ();
                    dialog.Closed += (s, e) => onDialogClosed();
                    var result = dialog.ShowDialog();
                    return result;
                }

            }
            catch (Exception)
            {

                throw;
            }
        }
    }
}

Prism 6 会自动执行此操作,对于 Prism 5,您需要遵循

ViewModelLocationProvider.SetDefaultViewModelFactory( type => Container.Resolve( type ) );

在您的引导程序 ConfigureContainer