嗨我试图通过棱镜中的viewmodel实例化视图而没有运气。显示窗口但没有更新任何模块区域。
请参阅下面的代码段:
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();
}
...
视图模型定义如下
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<TView>"/> 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; }
}
}
使用System; 使用System.ComponentModel; 使用System.Threading; 使用System.Windows.Threading;
/// ///所有视图模型的基类 /// public abstract class 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 :(得分:0)
虽然这样做有效,但我没有看到差异。
ShellWindow view = new ShellWindow();
ShellViewModel viewModel = new ShellViewModel(view);
return viewModel.View as DependencyObject;
答案 1 :(得分:0)
使用名称在UnityContainer中注册类型时,您还必须通过指定该名称来解决它。您还必须使用您注册的类型来解决。
container.RegisterType<Object, ShellViewModel>("ShellViewModel");
shellViewModel = container.Resolve<Object>("ShellViewModel") as ShellViewModel;
您还应该为ShellViewModel类定义一个接口,并使用该接口注册/解析。
public interface ShellViewModel
{
}
您的引导程序将如下所示:
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;
}
}