2016-07-19 16 views
0

verdrahtet: WPF Prism 5, UnityPrism 5 und Unity Verwendung manuell Ansicht lösen mit Ansichtsmodell

Ich versuche zu schreiben, was ich einen „WindowDialogService“ nennen, die, wenn sie eine Art geführt und rief, öffnet ein Fenster mit diesem Typ als Inhalt. Mein Problem ist, dass ich das ViewModel nicht zum Instanziieren und Verknüpfen mit der Ansicht erhalten kann.

Ich weiß nicht, ob es richtig ist, aber ich bin AutoWireViewModel in meiner Ansicht mit und wurde unter der Annahme (offensichtlich falsch), dass das Ansichtsmodell würde „liegt“, wenn die Einheit Container Lösung unter Verwendung dh container.TryResolve <T>()

Also im Grunde Ich kann die Ansicht auflösen, aber der DataContext der Ansicht ist null.

Ich habe alle relevanten Code unten enthalten.

Ansicht

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

Ansichtsmodell

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 Schnittstelle

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

WindowDialogService Implementierung

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

Antwort

2

Prism 6 tut dies automatisch, für Prism 5 Sie etwas entlang der Linien von

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

in Ihrer Bootstrap des

+0

Dank Haukinger benötigen. Ich habe das versucht, aber es scheint das Problem nicht zu beheben. Gibt es noch etwas, das ich in meinem Code ändern muss? Ich habe diese Codezeile (genau wie gezeigt) in meinem ConfigureContainer in meinem Bootstrapper abgelegt. Ist die Art, wie ich die Ansicht aufnehme (UnityContainer neu erstellen und TryResolve verwenden) korrekt? –

+0

Ich würde den One Unity-Container aus dem Bootstrapper verwenden (habe es als Abhängigkeit von Ihrem Dienst injiziert), nur für den Fall, dass Ihr Fenster irgendwelche Abhängigkeiten hat. Und natürlich müssen alle Abhängigkeiten Ihres Ansichtsmodells mit dem Container registriert werden, der zum Auflösen des Ansichtsmodells verwendet wird. – Haukinger

+0

Ok, mein Schlechter! * Dumb * Ich habe kürzlich ein Upgrade auf Prism 6 durchgeführt, was zu einer brechenden Änderung geführt hat, dass die View nicht in "View" enden kann (bzw. ViewModels kann nicht in "ViewViewModel" enden. Siehe hier: github.com/PrismLibrary/Prism. Markiert deins als richtige Antwort, da es die gestellte Frage anspricht ;-) –