2013-07-19 2 views
0

안녕하세요 프리즘 뷰 모델을 통한 뷰를 행운으로 인스턴스화하려고합니다. 창이 표시되지만 모듈 영역이 갱신되지 않습니다. 시스템을 사용하여프리즘에서 뷰 모델을 통한 뷰의 인스턴스화

public class ShellViewModel : ViewModelBase<IShellView> 
    { 
     public ShellViewModel([Dependency("ShellView")]IShellView view) 
      : base(view) 
     { 
     } 
    } 

public interface IShellView : IView 
    { 
     void ShowMessageInOutputWindow(string message); 
    } 

/// <summary> 
    /// Abstract base class for a ViewModel implementation. 
    /// </summary> 
    /// <typeparam name="TView">The type of the view. Do provide an interface as type and not the concrete type itself.</typeparam> 
    public abstract class ViewModelBase<TView> : ViewBase where TView : IView 
    { 
     /// <summary> 
     /// The view. 
     /// </summary> 
     private readonly TView view; 

     /// <summary> 
     /// Initializes a new instance of the <see cref="ViewModel&lt;TView&gt;"/> class and 
     /// attaches itself as <c>DataContext</c> to the view. 
     /// </summary> 
     /// <param name="view">The view.</param> 
     protected ViewModelBase(TView view) 
      : base(view) 
     { 
      this.view = view; 
     } 

     /// <summary> 
     /// Gets the associated view as specified view type. 
     /// </summary> 
     /// <remarks> 
     /// Use this property in a ViewModel class to avoid casting. 
     /// </remarks> 
     public TView View 
     { 
      get { return this.view; } 
     } 
    } 

을 다음과 같이

public class Bootstrapper : UnityBootstrapper 
    { 
     private ShellViewModel shellViewModel; 

     protected override DependencyObject CreateShell() 
     { 
      // register shell types 
      var container = ServiceLocator.Current.GetInstance<IUnityContainer>(); 
      container.RegisterType<IShellView, ShellWindow>("ShellView"); 
      container.RegisterType<Object, ShellViewModel>("ShellViewModel"); 
      shellViewModel = container.Resolve<ShellViewModel>(); 
      this.Shell = shellViewModel.View as DependencyObject; 
      return this.Shell; 
      //return new ShellWindow(); 

     } 
... 

그리고 뷰 모델 정의된다 :

아래 코드를 참조하십시오 using System.ComponentModel; using System.Threading; using System.Windows.Threading; 모든 뷰 모델 /// 공공 추상 클래스 ViewBase에 대한

/// /// 기본 클래스 : INotifyPropertyChanging는 { /// ///보기에서 INotifyPropertyChanged. /// 개인 읽기 전용 IView보기;

/// <summary> 
/// Initializes a new instance of the <see cref="ViewModelBase"/> class and 
/// attaches itself as <c>DataContext</c> to the view. 
/// </summary> 
/// <param name="view">The view.</param> 
protected ViewBase(IView view) 
{ 
    if (view == null) 
    { 
     throw new ArgumentNullException("view"); 
    } 

    this.view = view; 

    // Check if the code is running within the WPF application model 
    if (SynchronizationContext.Current is DispatcherSynchronizationContext) 
    { 
     // Set DataContext of the view has to be delayed so that the ViewModel can initialize the internal data (e.g. Commands) 
     // before the view starts with DataBinding. 
     Dispatcher.CurrentDispatcher.BeginInvoke((Action)delegate 
     { 
      this.view.DataContext = this; 
     }); 
    } 
    else 
    { 
     // When the code runs outside of the WPF application model then we set the DataContext immediately. 
     this.view.DataContext = this; 
    } 
} 

#region INotifyPropertyChanging Members 

public event PropertyChangingEventHandler PropertyChanging; 

#endregion 

#region INotifyPropertyChanged Members 

public event PropertyChangedEventHandler PropertyChanged; 

#endregion 

#region Administrative Properties 

/// <summary> 
/// Whether the view model should ignore property-change events. 
/// </summary> 
public virtual bool IgnorePropertyChangeEvents { get; set; } 

#endregion 

#region Public Methods 

/// <summary> 
/// Raises the PropertyChanged event. 
/// </summary> 
/// <param name="propertyName">The name of the changed property.</param> 
public virtual void RaisePropertyChangedEvent(string propertyName) 
{ 
    // Exit if changes ignored 
    if (IgnorePropertyChangeEvents) return; 

    // Exit if no subscribers 
    if (PropertyChanged == null) return; 

    // Raise event 
    var e = new PropertyChangedEventArgs(propertyName); 
    PropertyChanged(this, e); 
} 

/// <summary> 
/// Raises the PropertyChanging event. 
/// </summary> 
/// <param name="propertyName">The name of the changing property.</param> 
public virtual void RaisePropertyChangingEvent(string propertyName) 
{ 
    // Exit if changes ignored 
    if (IgnorePropertyChangeEvents) return; 

    // Exit if no subscribers 
    if (PropertyChanging == null) return; 

    // Raise event 
    var e = new PropertyChangingEventArgs(propertyName); 
    PropertyChanging(this, e); 
} 

}

#endregion 


/// <summary> 
    /// Represents a view 
    /// </summary> 
    public interface IView 
    { 
     /// <summary> 
     /// Gets or sets the data context of the view. 
     /// </summary> 
     object DataContext { get; set; } 

     /// <summary> 
     /// Initializes the view 
     /// </summary> 
     void Initialize(); 
    } 
+0

. 그리고 DI로 구성 루트 만 IoC 컨테이너를 알고 있습니다. 당신은 View의'DataContext'가 어디에 할당되어 있는지 보여주지 않을 것입니다, 저는'ViewModelBase <>'로 가정하고 있습니다 - 저는 최근에 그렇게했습니다. 그리고 IoC 컨테이너 (View에 ViewModel을 주입하는 것)를 뒤집습니다. 보기의 생성자를 호출하고 ViewModel없이 View를 얻고 있는데, 이것이 귀하의 쟁점 인 것 같습니다. –

답변

0

이 비록 작동하지만 난 그 차이를 볼 수 없습니다 이렇게.

ShellWindow view = new ShellWindow(); 
      ShellViewModel viewModel = new ShellViewModel(view); 
      return viewModel.View as DependencyObject; 
0

이름을 사용하여 UnityContainer에 유형을 등록 할 때 이름을 지정하여 해결해야합니다. 또한 등록한 유형을 사용하여 해결해야합니다.

container.RegisterType<Object, ShellViewModel>("ShellViewModel"); 
shellViewModel = container.Resolve<Object>("ShellViewModel") as ShellViewModel; 

또한 ShellViewModel 클래스의 인터페이스를 정의하고 해당 인터페이스를 사용하여 등록/해결해야합니다.

public interface ShellViewModel 
{ 
} 

귀하의 부트 스트 래퍼는 다음과 같을 것이다 : MVVM와 뷰 모델은 어떤보기 알고하지 않습니다

public class Bootstrapper : UnityBootstrapper 
{ 
    private IShellViewModel shellViewModel; 

    protected override DependencyObject CreateShell() 
    { 
     // register shell types 
     var container = ServiceLocator.Current.GetInstance<IUnityContainer>(); 
     container.RegisterType<IShellView, ShellWindow>("ShellView"); 
     container.RegisterType<IShellViewModel, ShellViewModel>("ShellViewModel"); 
     shellViewModel = container.Resolve<IShellViewModel>("ShellViewModel"); 
     this.Shell = shellViewModel.View as DependencyObject; 
     return this.Shell; 

    } 
}