将MessageDialog / MessageBox与可移植类库和MVVM Light一起使用

时间:2013-07-24 14:24:54

标签: windows-phone-8 windows-store-apps mvvm-light portable-class-library

我正在开发一个可用于Windows Phone 8和Windows应用商店的应用。为了减少冗余,我使用了可移植类库(PCL),最重要的是我试图在MVVM Light PCL Toolkit的帮助下应用MVVM模式。 ViewModel放置在PCL中,并直接绑定在Apps页面的XAML中。

收到数据时没有错误,一切正常。但是,当发生错误时,我不知道如何将异常/错误消息发回给应用程序。

Windows Store App内部错误将显示为MessageDialog,而Wp8应用程序将使用MessageBox类。显然,PCL并不知道这些类中的任何一个。我没有得到的是如何知道ViewModel是否遇到错误,以及如何在App中获取消息。当ViewModel绑定在XAML中时,这是否可能?

ViewModel (PCL内部)中的代码如下所示:

DataService.Authenticate((token, error) =>
{
    if (error != null)
    {
        // This is, obviously, not going to work.
        MessageBox.Show(error.Message);
        return;
        }

    Token = token;
});

所以我必须以某种方式保存错误让App本身知道发生了错误,然后调用匹配的方式向用户显示错误。

目前我正在考虑在BaseViewModel中定义Error-property并在ViewModel中发生错误时填充它。然后,在页面的CodeBehind中,让他们知道当前的ViewModel并将PropertyChanged事件绑定到此Error-property。但我还没有实现它,所以我不知道这是否是正确的方法。

我是否必须退出想法,将ViewModel绑定在XAML中,我是否必须在Codebehind页面内初始化它们?

1 个答案:

答案 0 :(得分:0)

你的直觉是正确的,但有很多方法可以解决这个问题。

首先,您可以使用Mvvm的Messaging库,这将允许您的ViewModel直接向您的View发送消息。然后,您的视图可以按照自己的意愿处理,包括但不限于使用MessageDialog

其次,您还可以在ViewModelLocator中为ShowMessageDialog创建一个功能或操作(可能是前者)。此函数可能需要string并返回Task。然后,在初始化ViewModelLocator之后,您可以注入ShowMessageDialog代码。然后,您的ViewModels可以使用他们所喜欢的任何平台MessageDialogs

例如:

注意:此代码使用Nuget中可访问的BCL异步库。他们在PCL工作就好了。

ViewModelLocator:

public static Func<string, Task> ShowMessageDialog { get; set; }

App.xaml.cs:

ViewModelLocator.ShowMessageDialog = (message) => 
    {
        // For Windows Phone
        return TaskFactory.StartNew(() => MessageBox.Show(message));

        // For Windows 8
        MessageDialog md = new MessageDialog(message);
        return md.ShowAsync().AsTask();
    };

视图模型:

await ViewModelLocator.ShowMessageDialog("This is my message.");

次要注意:必须在UI线程上运行md.ShowAsync().AsTask(); 。这意味着如果您在异步中在任务中运行它,则必须通过调度程序调用它。这可以使用类似的方法通过RunAsync方法注入应用程序的CoreDispatcher。

这意味着您可以在任何平台(如上所示的Windows 8和Windows Phone)上注入您想要的任何Message Dialog系统并在PCL中使用它。

我会说我建议的第一种方法要容易得多,因为它就是这样,但是Function方法版本肯定是有用的。