2

我目前正在使用 MVVM (Light) 使用 WPF 构建应用程序。但是,在某些情况下,当用户单击按钮时,我必须打开一个新对话框(也是 WPF)。然而,这是一场硬仗。

这是我的做法:

    private void _ShowItemDialog(Item item)
    {
        var itemVM = new ItemViewModel();
        itemVM.CurrentItem = item ?? new Item();
        itemVM.Load();

        var itemView = new View.ItemView() { DataContext = itemVM };
        if (itemView.ShowDialog() == true)
        {
            if (item == null)
            {
                itemList.Add(itemVM.CurrentItem);
            }
        }

        itemVM.Cleanup();
    }

并且 itemView XAML 没有绑定到 DataContext,否则会创建两个不同的 ViewModel 实例。

在 Window 标签内。为了在 ShowDialog 获得结果,我使用 DialogCloser 代码:

    public static class DialogCloser
    {
        public static readonly DependencyProperty DialogResultProperty =
            DependencyProperty.RegisterAttached(
                "DialogResult",
                typeof(bool?),
                typeof(DialogCloser),
                new PropertyMetadata(DialogResultChanged));

        private static void DialogResultChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var window = d as Window;
            if (window != null)
                window.DialogResult = e.NewValue as bool?;
        }

        public static void SetDialogResult(Window target, bool? value)
        {
            target.SetValue(DialogResultProperty, value);
        }
    }

在 ItemView 中,这是在 Window 标记内声明的,如下所示:

my:DialogCloser.DialogResult="{Binding DialogResult}"

并且当对话框关闭时,关闭事件将 DialogResult 设置为 true 或 false。

这在第一次打开屏幕时非常有效,但在关闭后无法再次打开对话框。

我想知道您是否对打开对话框有更好的想法,以及为什么此代码不起作用。

谢谢!

编辑: 我已经修复了代码。我需要做的是创建一个新的 ViewModel 并将其附加到 DataContext 每次打开对话框时。此外,我必须从 XAML 中删除 DataContext 绑定。请检查上面的代码更改。

通过这些更改,我发现无法使用 ViewModelLocator 中的 ViewModel,因为它是“单例”,而不是每个新窗口中的新实例。因此,DialogResult 保留了最后一个值,如果我尝试将其值更改回 null(就像初始化 ViewModel 时一样),则会引发异常。你对为什么会发生这种情况有任何线索吗?使用 ViewModelLocator 中的 ViewModel 对我来说非常好,因为它会在整个系统中保持相同的策略。

谢谢!

4

2 回答 2

0

我通过实现静态 XxxxInteraction 类来做到这一点,这些类具有调用例如 NewUser(); 的方法;该方法打开对话框并做一些工作。在我的 ViewModel 中,我通过命令调用 XxxxInteraction 类。

这种实现方式的努力在于,您可以轻松地修改静态交互类中的方法以使用单元测试。

    public static class UserInteractions
    {
        public static User NewUser()
        {
            var userDialog = new NewUserDialog();
            If(userDialog.ShowDialog() != true) return null;

            var user = new User();
            user.Name = userDialog.Name;
            user.Age = userDialog.Age;
            return user;
        }
    }

    public class MyViewModel
    {
        ...

        public void NewUserCommandExecute()
        {
            var newUser = UserInteractions.NewUser();
            if(newUser == null) return;

            //Do some with new created user
        }
    }

NewUserDialog 也是一个绑定到 ViewModel 的普通窗口。

我认为这是为 mvvm 模式实现对话框的好方法。

于 2012-08-06T19:18:14.487 回答
0

我前段时间做过,我使用对话服务并在我的视图模型中调用此服务。看看

编辑:顺便说一句,这就是你在视图模型中要做的所有事情

var result = this.uiDialogService.ShowDialog("Dialogwindow title goes here", dialogwindowVM);
于 2012-08-07T05:28:38.140 回答