暂停用户输入的视图模型进程
我一直在查看典型的“从视图模型引发对话框”问题的视图示例,注意到 3 个主要解决方案:
- 使用附加行为
- 使用中介模式
- 使用服务
我有点陷入困境,并努力寻找解决方案这很容易适合我的问题空间 - 这是一个非常简单的文件复制问题:
- 我的视图模型正在处理循环(复制文件列表)
- 当文件已存在于目的地时,我需要引发一个模式对话框以确认替换
- 虚拟机需要等待并接收确认,然后才能继续
- “模式对话框”实际上不是一个新窗口,而是我的主窗口中的隐藏覆盖层,按照 http://www.codeproject.com/KB/WPF/wpfmodaldialog.aspx (谢谢罗纳德!)
我大部分时间都在那里,但我遇到的最大的困难是: - 如何在等待输入时暂停视图模型中的循环 - 如何在循环内将输入返回到视图模型,以便它可以继续到目前为止
,我倾向于服务解决方案,因为它似乎是一个直接方法调用,并带有虚拟机必须等待的返回值。但是,这是否意味着服务需要直接绑定到视图才能使元素可见?
如果有人可以发布一些直接处理这个问题的简单代码,我(和网络)将非常高兴!谢谢!
I've been looking at a view examples of the typical "raise dialog from viewmodel" problem, noting 3 main solutions:
- use attached behaviors
- use a mediator pattern
- use a service
I'm getting a bit bogged down though and struggling to find a solution that easily fits into my problem space - which is a very simple file copy problem:
- My viewmodel is processing a loop (copying a list of files)
- When a file already exists at the destination I need to raise a modal dialog to get confirmation to replace
- The vm needs to wait for and receive confirmation before continuing
- The "modal dialog" is actually not a new window but a hidden overlay in my MainWindow, as per http://www.codeproject.com/KB/WPF/wpfmodaldialog.aspx (thanks Ronald!)
I'm mostly there but the biggest struggles I have are:
- how to pause the loop in the viewmodel while it waits for input
- how to get input back to the viewmodel within the loop so it can carry on
So far I'm leaning towards the service solution because it seems a direct method call with a return that the vm must wait for. However, it does mean the service needs to tie directly to the view in order to make an element visible?
If anyone can post some simple code that deals directly with this problem I (and the net) would be very happy! Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
例如,您有一个名为
IDialogService
的服务,具有以下接口:正如您所提到的,为了使该服务能够显示实际的对话框,它需要引用将要显示的视图实际的覆盖元素。但我更喜欢通过接口引用它,而不是直接引用视图。我们将其称为
ICanShowDialog
,它将具有以下成员:该接口将由拥有对话框覆盖层的视图(例如您的主窗口)实现。
现在有趣的部分是:在显示对话框时暂停代码执行。首先,我建议您不要使用覆盖元素,而尽可能使用常用的窗口。那么你就不会有这个问题了。您可以设置对话框窗口的样式,使其看起来就像覆盖元素一样。
无论如何,如果您仍然想使用覆盖元素,那么您可以执行以下技巧来暂停代码执行:
以下是
IDialogService
接口的ConfirmAction
方法的伪代码:这是
DispatcherUtils.DoEvents()
的代码(取自此处:http://dedjo.blogspot.com/2007/08/how-to-doevents-in-wpf.html):但我必须警告你。使用 DoEvents 可能会导致一些由内部调度程序循环引起的微妙错误。
作为在显示对话框时暂停代码执行的替代方法,您可以使用回调:
但使用起来不太方便。
For example, you have a service called
IDialogService
with the following interface:As you mentioned, in order for the service to be able to show the actual dialog it needs to have a reference to the view that will show the actual overlay element. But instead of directly referencing the view I prefer to reference it via an interface. Lets call it
ICanShowDialog
and it will have the following members:This interface will be implemented by your view that owns the dialog overlay (e.g. your main window).
Now the interesting part: suspending the code execution while the dialog is shown. First of all, I would recommend you not to use overlay elements but use usual windows if possible. Then you will not have that problem. You can style the dialog window so it will look just like the overlay element.
Anyway, if you still want to use overlay elements then you can do the following trick to suspend the code execution:
Here is pseudo code of the
ConfirmAction
method of theIDialogService
inteface:Here is the code of
DispatcherUtils.DoEvents()
(that was taken from here: http://dedjo.blogspot.com/2007/08/how-to-doevents-in-wpf.html):But I must warn you. Using
DoEvents
can result in some subtle bugs caused by inner dispatcher loops.As an alternative to suspending the code execution while a dialog is shown you can use callbacks:
But it will not be so convenient to use.