【问题标题】:Setting datacontext with prism用棱镜设置数据上下文
【发布时间】:2013-02-14 07:53:18
【问题描述】:

我正在尝试使用 PRISM 创建一个模块,现在我在视图中设置了 DataContext,这意味着我只能使用无参数构造函数,但这意味着我不能在我的构造函数中使用依赖注入(我使用 Unity)想要

如果可能的话,我不希望视图或虚拟机相互了解,并希望使用类似的东西

private void RegisterServices()
{
    var employeeViewModel = new EmployeeViewModel();

    _container.RegisterType<IEmployeeViewModel, EmployeeViewModel>();
    _container.RegisterType<EmployeeView>();

    EmployeeView.Datacontext = employeeViewModel;
}

我将在 EmployeeModule 中注册

这是可能的还是我应该使用后面的代码?

【问题讨论】:

    标签: c# wpf dependency-injection prism unity-container


    【解决方案1】:

    您可以将ViewModel 的接口传递给构造函数中的View。这样View只知道ViewModel的接口,ViewModelView一无所知。

    例如

    public class EmployeeView : UserControl
    {
        public EmployeeView(IEmployeeViewModel vm)
        {
             this.DataContext = vm; //// better to set the ViewModel in the Loaded method
        }
    }
    

    有关 MVVM 实例化的多种方法,请参阅 this blog post

    【讨论】:

    • 但后面的代码不可能没有任何东西?
    • 您可以将 ViewModel 创建为 xaml 中的资源;那么你不能使用统一容器。你可以为你的视图创建一个基类,然后你只需要在后面的代码中继承基类。您需要声明 ViewModel 和 View 之间的关系。请参阅问题中的链接。
    【解决方案2】:

    Prism documentation 给你一个选择

    通常,您会发现定义控制器或服务类很有用 协调视图和视图模型类的实例化。 这种方法可以与依赖注入容器一起使用,例如 作为 MEF 或 Unity,或者当视图显式创建其所需视图时 型号。

    对于我的模块,我会执行以下操作
    为模块内部的服务创建接口

    public interface ICustomModuleUiService
    {
        void ShowMainView();
        void ShowExtraView();
    }
    

    同一模块中的生产实现:

    class CustomModuleUiService : ICustomModuleUiService
    {
        private readonly IEventAggregator _eventAggregator;
    
        public CustomModuleUiService(IEventAggregator eventAggregator)
        {
            _eventAggregator = eventAggregator;
        }
    
        public void ShowMainView()
        {
            var ddsViewModel = new DdsViewModel(_eventAggregator, this);
            DdsForm form = new DdsForm();
            form.DataContext = ddsViewModel;
            form.Show();
        }
    
        public void ShowExtraView()
        {
            //some code here
        }
    }
    

    最后是模块代码

    [ModuleExport("DssModule", typeof(DssModuleImpl))]
    public class DssModuleImpl : IModule
    {
        private readonly IEventAggregator _eventAggregator;
        private ICustomModuleUiService _uiService;
    
        [ImportingConstructor]
        public DssModuleImpl(IEventAggregator eventAggregator)
        {
            _eventAggregator = eventAggregator;
            _uiService = new CustomModuleUiService(_eventAggregator);
        }
    
        public void Initialize()
        {
            _eventAggregator.GetEvent<OpenDdsFormEvent>().Subscribe(param => _uiService.ShowMainView());
        }
    }
    

    使用这种方法我会得到

    • ViewModel 可以进行单元测试
    • 我可以通过替换 ICustomModuleUiService 的实现来动态更改对 OpenDdsFormEvent 的反应

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-25
      • 2013-08-18
      • 2023-03-08
      相关资源
      最近更新 更多