【问题标题】:Prism 5 and Unity - Manually resolve View with ViewModel wired upPrism 5 和 Unity - 使用已连接的 ViewModel 手动解析视图
【发布时间】:2016-07-19 13:40:51
【问题描述】:

使用: WPF、Prism 5、Unity

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

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

所以基本上,我可以解析视图,但视图的 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>

视图模型

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;
        }
    }

WindowDialogService 实现

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;
            }
        }
    }
}

【问题讨论】:

    标签: wpf prism prism-5


    【解决方案1】:

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

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

    在你的引导程序的ConfigureContainer

    【讨论】:

    • 谢谢豪金格。我试过这个,但它似乎并没有解决这个问题。我的代码中还有其他需要更改的地方吗?我将那行代码(如图所示)放入我的引导程序中的 ConfigureContainer 中。我解析视图的方式(新建 UnityContainer 并使用 TryResolve)是否正确?
    • 我会使用引导程序中的一个统一容器(将其作为服务的依赖项注入),以防您的窗口有任何自己的依赖项。当然,您的视图模型的所有依赖项都必须注册到用于解析视图模型的容器中。
    • 好吧,我的错! Dumb 我最近升级到 Prism 6,导致 View 不能以“View”结尾(以及 ViewModel 不能以“ViewViewModel”结尾。请参见此处:github.com/PrismLibrary/Prism . 将您的答案标记为正确答案,因为它确实解决了所提出的问题;-)
    • 视图可以以View结尾,但视图模型以ViewModel(不是ViewViewModel)结尾...
    猜你喜欢
    • 2012-01-26
    • 2011-12-15
    • 1970-01-01
    • 1970-01-01
    • 2016-08-30
    • 2017-06-26
    • 2019-04-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多