情景:
dialog.DialogResult == true
),并且它应该刷新它的数据和任何相关的绑定还要考虑步骤3可能由于某种原因而失败(复杂的业务逻辑规则可能会失败并且用户需要调整某些内容,数据库更新可能会引发异常,僵尸入侵等),因此编辑对话框可能有保持开放。
ViewModels不应该(根据我的理解)知道很多关于其相关View的内容,因此,ViewModel很难与View进行通信:
“嘿,保存操作成功完成!继续关闭吧!”
或者:
“哇!在你关闭之前有一个问题需要注意......等一下。”
问题:
如何使用xaml.cs
代码(最好没有代码)完成优雅这样的事情?
答案 0 :(得分:3)
通常在执行此类操作时,我会将对话框窗口的打开关闭到服务,以后可以进行模拟以进行测试。类似的东西:
public interface IDialogProvider
{
bool OpenDialog(IViewModel viewModel)
}
然后传入的viewmodel可以绑定设置为模态窗口的DataContext,并且通过数据模板化将使用正确的视图。
当触发命令打开子项时,父视图模型可以使用此服务。孩子可以完成所需的所有处理,并且可以从孩子那里获得所需的任何信息,以获得真实的结果:
public void ExecuteEdit()
{
ChildViewModel childViewModel = GetViewModelForSelectedItem();
if (_dialogProvider.OpenDialog(childViewModel)
{
//child view model saved, trigger rebinding etc...
}
}
如果你有这些对话框使用的视图模型的特定基类来处理错误场景,你可以使用一些代码来处理关闭窗口。我在视图模型中使用视图不可知事件,并在触发此事件时关闭窗口。在视图中:
public DialogWindowView()
{
InitializeComponent();
DataContexctChanged += HandleDataContextChanged;
}
private void HandleDataContextChanged(object sender, EventArgs e)
{
IDialogViewModel viewModel = DataContext as IDialogViewModel;
if (viewModel != null)
{
viewModel.ActionSuccessful += HandleActionSuccessful
}
}
private void HandleActionSuccessful(object sender, EventArgs e)
{
DialogResult = DialogResult.OK;
Close();
}
我完全没有问题,因为这个代码是视图,因为viewmodel不负责处理事物的样子,包括打开或关闭窗口。如果你完全反对代码背后的想法,或者你不想将视图耦合到viewmodel类型,你可以将责任转移到DialogProvider:
public class DialogProvider : IDialogProvider
{
public bool OpenDialog(IDialogViewModel viewModel)
{
Window dialog = new DialogWindow();
dialog.DataContext = viewModel;
bool success = false;
viewModel.ActionSuccessful = (o, e) =>
{
dialog.Close();
success = true;
}
dialog.ShowDialog();
return success;
}
}
答案 1 :(得分:1)
您的EditDialog可能具有IsVisible属性,对话框可见性绑定到该属性。如果保存失败,请将IsVisible属性设置为true,否则将其设置为false。由于它是绑定的,它应该在保存成功时自动隐藏Popup,或者如果失败则保持打开。
答案 2 :(得分:1)
好问题。
MVVM模式声明View应该数据绑定到ViewModel.Properties。 View可以通过调用ViewModel.Commands(View => VM)来触发操作
因此,ViewModel将某些内容传递回View的唯一方法是通过Properties(即PropertyChangedNotifications)。视图必须绑定到VM上的某个属性并进行更改,以决定是否自行关闭。
答案 3 :(得分:0)
我滚动了我自己的窗口加载器,我在这里的回答中有描述: