我今天大部分时间都在尝试理解在WPF / MVVM中关闭对话框的许多不同方法。大多数答案都集中在简单的对话框上 - 例如是/否确认对话框。但是,似乎没有人描述一个实际执行某些操作的对话框的更复杂的情况,这些操作必须以事务方式提交:全有或全无。
有一个OK按钮,单击该按钮可在ViewModel上调用绑定命令。一切都很好。
现在,如果命令成功,我想关闭窗口,但如果命令失败,我不想关闭它。
经过数小时的研究后,我得出的结论是,世界上似乎没有人遇到类似的问题需要解决:|
我发明但尚未实施的解决方案如下:
我会有一个ConditionalCloseWindow
命令,它将窗口作为参数,然后关闭窗口。
ConditionalCloseWindow
命令会附加属性:
public static readonly DependencyProperty Condition = DependencyProperty.RegisterAttached("Condition", typeof(ICommand), ... snip
执行ConditionalCloseWindow
命令首先会导致执行Condition
命令。只有成功执行Condition
命令,ConditionalCloseWindow
才会实际执行Close()
。
您如何看待这样的解决方案?它完全无效吗?或许它是一种公认的模式,我没有通过我的研究成功发现?
答案 0 :(得分:1)
一种方法是在ViewModel中设置Closing事件处理程序,例如:
<i:Interaction.Triggers>
<i:EventTrigger EventName="Closing">
<command:EventToCommand Command="{Binding WindowClosing}" />
</i:EventTrigger>
</i:Interaction.Triggers>
ViewModel中的:
public ICommand WindowClosing
{
get
{
return _windowClosing ?? _windowClosing = new RelayCommand<CancelEventArgs>(
(args) =>{
if(somethingDoesNotMakeSense)
args.Cancel = true;
});
}
}
虽然这可能会有点混乱。
我想到的另一个人;
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<commandCall Command="ButtonClicked" />
<commmandCall Command="CloseWindow" Parameter="{Binding VIewModelCanWeClose}" />
</i:EventTrigger>
</i:Interaction.Triggers>
CloseWindow应该是命令,在Codebehind中实现,它将获取参数“我们应该关闭还是不关闭”并根据它调用Close()。
答案 1 :(得分:0)
有很多方法可以解决您的问题。我的第一个建议是,你的对话框ViewModel有一个类型为action的属性。您的对话框将该属性设置为关闭对话框的操作。在您的命令中,您可以调用该操作,对话框将关闭。
答案 2 :(得分:0)
有各种“表单”控件允许您编排事物,例如支持验证,取消/确定逻辑,关闭等。
http://wpfdataform.codeplex.com/(不确定状态,但它正在尝试复制Silverlight DataForm)。
http://www.silverlightshow.net/items/ModalDialogs-IEditableObject-and-MVVM-in-Silverlight-4.aspx(向您展示如何构建“模态”对话框的行为...基于Silverlight但如果WPF不相同则应该关闭。
您可以在“模型”上使用IEditableObject以事务方式处理更改提交。