Tomás
Tomás

Reputation: 555

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

Using: WPF, Prism 5, Unity

I am trying to write what I call a "WindowDialogService" which, when passed a type and called, will open a Window with that type as the content. My problem is I cannot get the ViewModel to instantiate and associate to the View.

I don't know if it is right but I am using AutoWireViewModel in my View and was assuming (obviously incorrectly) that the ViewModel would be "Located" when resolving using the Unity Container i.e. container.TryResolve <T> ()

So basically, I can resolve the View but the DataContext of the view is null.

I have included all relevant code below.

View

<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 Interface

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

WindowDialogService Implementation

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

Upvotes: 0

Views: 874

Answers (1)

Haukinger
Haukinger

Reputation: 10863

Prism 6 does this automatically, for Prism 5 you need something along the lines of

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

in your bootstrapper's ConfigureContainer

Upvotes: 1

Related Questions