我正在使用caliburn为MVVM制作一个小型演示应用程序。
现在我想显示MessageBox
,但是MVVM方式。
对于我创建了一个事件的对话框,它在ShellView
(根视图)中处理
并使用Dialogs WindowManager.ShowDialog
类型调用ViewModel
。
似乎坚持使用MVVM。
但是显示消息框并获得结果的方式是什么(好的还是取消)?
我已经看过this question,但它也没有回答。
艾森伯格先生自己回答
“Caliburn内置了调用自定义消息框的服务。”
任何人都能说出他的意思吗?我没有在样本中看到它。
答案 0 :(得分:5)
在文章A Billy Hollis Hybrid Shell (由框架协调员编写)中,作者展示了处理对话框和消息框的好方法,但是他使用了依赖注入(你可以当然没有DI,但它会让事情更简单)。主要的想法是你可以让你的主窗口,一个用作应用程序shell的窗口实现一个如下所示的界面:
public interface IDialogManager
{
void ShowDialog(IScreen dialogModel);
void ShowMessageBox(string message, string title = null, MessageBoxOptions options = MessageBoxOptions.Ok, Action<IMessageBox> callback = null);
}
然后他将此界面注册到IoC容器中,我猜你可以从那里开始使用你的想象力,如果你没有时间,那么你可以查看文章附带的source code。
答案 1 :(得分:4)
正如您所提到的,您只需准备视图模型(例如ConfirmationBoxViewModel
)和适当的视图。您必须创建两个操作(从Screen
继承视图模型之后,这是使用TryClose
所必需的。您可以始终实现IScreen
,但这样做会更多) :
public void OK()
{
TryClose(true);
}
public void Cancel()
{
TryClose(false);
}
然后在您的其他视图模型中:
var box = new ConfirmationBoxViewModel()
var result = WindowManager.ShowDialog(box);
if(result == true)
{
// OK was clicked
}
请注意,对话框关闭后,如果需要从对话框中提取其他数据(例如,选定项目,显示名称等),则可以访问视图模型属性。
答案 2 :(得分:0)
当root / main / shell视图模型实现一种 DialogService 接口时,需要显示对话框的每个其他视图模型最终都会依赖于根视图模型。有时这可能不是很令人沮丧,例如如果它可能导致依赖循环:
DialogService (又名 RootViewModel ) - &gt; SomeViewModel - &gt; RootViewModel
打破此依赖关系链(实际上将其反转)的更多参与方法如下:
Window.OnSourceInitialized
事件的行为,并将其附加到主视图Window
组件。这是窗口句柄可用时触发的事件。在事件发生时,行为将通过附加属性通知传入的处理程序:<my:WindowSourceBehavior InitListener="{Binding WindowListener}" />
public class WindowSourceBehavior : Behavior<Window>
{
// ...
// boilerplate code for IWindowListener InitListener dependency property
// ...
attachedWindow.SourceInitialized += (sender, evt) =>
{
// ...
InitListener.SourceInitialized(sender as Window);
}
}
public class DialogService : IWindowListener
{
// ...
public void SourceInitialized(Window rootWindow) { /* ... */ }
}
WindowListener
设置为 DialogService 处理程序/接口:public MainViewModel(IWindowListener dialogServiceInDisguise)
{
WindowListener = dialogServiceInDisguise;
}
public IWindowListener WindowListener { get; private set; }
这样做,DialogService能够获得root窗口,无论哪个视图模型需要显示对话框,都不会在主视图模型上创建(n间接)依赖。