首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用MVVM从WPF应用程序启动对话框/子窗口的标准方法

使用MVVM从WPF应用程序启动对话框/子窗口的标准方法
EN

Stack Overflow用户
提问于 2013-06-25 22:58:25
回答 6查看 10.5K关注 0票数 11

总之,我想知道使用MVVM模式从WPF启动子对话框/窗口的公认最佳方法/行业标准。我看到了以下文章:

A. CodeProject -在使用MVVM模式时显示对话框

这种方法似乎不错,但对我来说太过分了。这是某种程度的代码复制,我不相信这是正确的方法。

B. WPF MVVM和显示对话框

这简单地贯穿了三个选项,不同的链接,这些都是相当/非常差的解释方法或主题。

请有人解释一下使用MVVM从WPF应用程序中启动对话框的行业标准方法/方法,并最好提供一些指向进一步阅读材料的链接。如果你能自己举个例子,我当然会非常感激!

耽误您时间,实在对不起。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2013-06-25 23:57:13

首先,我不知道任何使用MVVM显示对话框的“行业标准”方法,因为没有这样的东西。

其次,欢迎来到MVVM,您刚刚谈到了MVVM没有标准的领域。

说实话,MVVM有很多痛苦之处,这就是为什么有大量的MVVM框架存在,仅举几个MVVM、PRISM、Caliburn.Micro、Cinch、Catel、WAF、Baboon、shell I stop或您想要的更多。

现在,为了回答您的问题,在处理了大多数这些框架之后,我注意到了一个共同点,它们都使用DI/IoC容器,然后为您提供一个接口,类似于IDialogManager以及它们自己的实现,然后他们要求您在视图模型中接受这个接口,并使用它来显示对话框。因此,总之,我将使用依赖项注入,有一个显示对话框的接口,然后提供并实现它,并将其注册到di容器中,然后从我的视图模型或视图中使用它。

编辑:,所以您已经选择了PRISM (在我看来)在它们之间显示对话框是最困难的。撇开这一点不谈,有一种困难的方法是使用交互请求 (查看本文的中间部分),或者您可以使用这个回答作为一种更快的方法。

票数 10
EN

Stack Overflow用户

发布于 2013-06-26 00:37:56

最近,我为WPF实现了我自己的导航服务,它使用了杯标( WindowManager )(但您可以用其他东西代替它)。

示例(如何使用):

代码语言:javascript
运行
复制
_navigationService.GetWindow<ClientDetailsViewModel>()
            .WithParam(vm => vm.IsEditing, true)
            .WithParam(vm => vm.Client, SelectedClient)
            .DoIfSuccess(() => RefreshSelectedClient())
            .ShowWindowModal();

Implementation:

代码语言:javascript
运行
复制
namespace ClientApplication.Utilities
{
    public class NavigationService : INavigationService
    {
        SimpleContainer _container;
        IWindowManager _windowManager;

        public NavigationService(SimpleContainer container, IWindowManager windowManager)
        {
            _container = container;
            _windowManager = windowManager;
        }

        public INavigationService<TViewModel> GetWindow<TViewModel>()
        {
            return new NavigationService<TViewModel>(_windowManager, (TViewModel)_container.GetInstance(typeof(TViewModel), null));
        }
    }




    public class NavigationService<TVM> : INavigationService<TVM>
    {
        IWindowManager _windowManager;
        TVM _viewModel;
        System.Action _action;

        public NavigationService(IWindowManager windowManager, TVM viewModel)
        {
            _windowManager = windowManager;
            _viewModel = viewModel;
        }

        public INavigationService<TVM> WithParam<TProperty>(Expression<Func<TVM, TProperty>> property, TProperty value)
        {
            var prop = (PropertyInfo)((MemberExpression)property.Body).Member;
            prop.SetValue(_viewModel, value, null);

            return this;
        }

        public INavigationService<TVM> DoBeforeShow(Action<TVM> action)
        {
            action(_viewModel);
            return this;
        }

        public INavigationService<TVM> DoIfSuccess(System.Action action)
        {
            _action = action;
            return this;
        }

        public void ShowWindow(IDictionary<string, object> settings = null)
        {
            _windowManager.ShowWindow(_viewModel, null, settings);
        }

        public bool ShowWindowModal(IDictionary<string, object> settings = null)
        {
            bool result = _windowManager.ShowDialog(_viewModel, null, settings) ?? false;
            if (result && _action != null)
                _action();

            return result;
        }
    }
}

接口:

代码语言:javascript
运行
复制
namespace Common
{
    public interface INavigationService<TVM>
    {
        INavigationService<TVM> WithParam<TProperty>(Expression<Func<TVM, TProperty>> property, TProperty value);

        INavigationService<TVM> DoIfSuccess(System.Action action);

        INavigationService<TVM> DoBeforeShow(Action<TVM> action);

        void ShowWindow(IDictionary<string, object> settings = null);

        bool ShowWindowModal(IDictionary<string, object> settings = null);
    }



    public interface INavigationService
    {
        INavigationService<TViewModel> GetWindow<TViewModel>();
    }
}
票数 2
EN

Stack Overflow用户

发布于 2013-06-26 01:02:17

最近发布的Prism (在这里下载)包含一个称为“股票交易”的MVVM应用程序的“参考实现”。我的理由是,如果Prism团队称它为“参考实现”,那么从他们的角度来看,这是最“标准”的(如果在MVVM中有标准的话),以及继续推进的逻辑选择。

源代码包含一个用于提高模态对话框的基础设施库,而且它非常好。因此,我采用了这个库,并成功地部署了它(我将这样的应用程序上传到Codeplex)。

我需要将代码调整为1,将父程序的图标添加到标题栏中,因为库没有为其提供;2向标题栏添加一些有意义的文本,因为库将其保留为空白,而3在对话框关闭时添加要调用的委托。抽象的程度是,VM可以通过向中介传递两个字符串(即统一注册名称)来引发对话。这些更改可在Codeplex上使用。

因此,在所有其他“标准”中,“参考实施”应尽可能少地作为一个可行的选择。对您的问题的更间接的回答是,如果您的View模型足够孤立,并且完全通过POCO接口工作,那么从理论上讲,这并不重要,因为切换到另一个“标准”应该是一个微不足道的练习。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17308945

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档