我目前正在使用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会非常好,因为它会在整个系统中保持相同的策略。
谢谢!
答案 0 :(得分:0)
我通过实现具有调用方法的静态XxxxInteraction类来实现,例如NewUser();那些方法打开了Dialogs并做了一些工作。在我的ViewModel中,我通过命令调用XxxxInteraction类。
这种实现方式的努力是,您可以轻松地修改静态Interaction类中的方法以使用UnitTests。
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模式对话框的好方法。
答案 1 :(得分:0)
我刚刚做过这个,我使用对话服务并在我的viewmodel中调用此服务。 take a look
编辑:顺便说一句,这就是你在viewmodel中所要做的一切var result = this.uiDialogService.ShowDialog("Dialogwindow title goes here", dialogwindowVM);