Caliburn ShowDialog和MessageBox

时间:2013-07-07 09:09:25

标签: c# wpf mvvm messagebox caliburn.micro

我正在使用caliburn为MVVM制作一个小型演示应用程序。

现在我想显示MessageBox,但是MVVM方式。

对于我创建了一个事件的对话框,它在ShellView(根视图)中处理 并使用Dialogs WindowManager.ShowDialog类型调用ViewModel。 似乎坚持使用MVVM。

但是显示消息框并获得结果的方式是什么(好的还是取消)?

我已经看过this question,但它也没有回答。

艾森伯格先生自己回答

  

“Caliburn内置了调用自定义消息框的服务。”

任何人都能说出他的意思吗?我没有在样本中看到它。

3 个答案:

答案 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);
  }
}
  • DialogService 按行为要求公开处理程序 - 或接口:
public class DialogService : IWindowListener
{
  // ...
  public void SourceInitialized(Window rootWindow) { /* ... */ }
}
  • 在根视图模型中,(间接)将 DialogService 注入为依赖项。在构造期间,将视图模型绑定属性WindowListener设置为 DialogService 处理程序/接口:
public MainViewModel(IWindowListener dialogServiceInDisguise)
{
  WindowListener = dialogServiceInDisguise;
}

public IWindowListener WindowListener { get; private set; }

这样做,DialogService能够获得root窗口,无论哪个视图模型需要显示对话框,都不会在主视图模型上创建(n间接)依赖。