使用MVVM模式时如何处理MessageBox对话框(MVVM Light ToolKit)

时间:2013-03-14 21:45:57

标签: c# windows-phone-7 mvvm mvvm-light

我正在制作Windows Phone 7并尝试使用MVVM。我想让我的视图模型尽可能干净,但我不确定如何制作一个对话框。我正在使用MVVM灯,我知道他们有消息系统或其他东西但不确定如何使用它。

我想使用Guide.BeginShowMessageBox,因为它似乎提供了比标准对话框更多的功能。

如何在不破坏MVVM模式的情况下执行此操作。当我加载视图时,我希望触发一个加载的触发器,然后检查一些条件。如果符合条件,请显示对话框。

// Vm

public RelayCommand MainPageLoaded
    {
        get
        {
            if (!NetworkInterface.GetIsNetworkAvailable())
            {
                // breaks MVVM now as have view code in viewmodel. Need to take out somehow
                Guide.BeginShowMessageBox("Test", "Test network", new List<string>() { "Yes", "No" }, 0, MessageBoxIcon.Warning, asyncResult =>
                    {
                        int? returned = Guide.EndShowMessageBox(asyncResult);
                        // if yes then work offline mode? Maybe another property in ViewModel will get set to say offline mode?
                    }, null);
            }
            return null;
        }
        set
        {
            // Not sure what to put here.
        }
    }

//查看

<i:Interaction.Triggers>
    <i:EventTrigger>
        <GalaSoft_MvvmLight_Command:EventToCommand Command="{Binding MainPageLoaded}"/>
    </i:EventTrigger>
</i:Interaction.Triggers>

修改 我遇到的另一个问题是。我有一个列表绑定到存储在此属性

中的某些数据
   public ObservableCollection<ContactGroup> ContactGroups { get; set; }

然后点击我有一个应该被触发的relaycommand

 public ICommand GroupContactTapped
        {
            get
            {
                return new RelayCommand<GestureEventArgs>(e =>
                {
                    var selectedTextBlock = e.OriginalSource as TextBlock;

                    MessageBox.Show(selectedTextBlock.Tag.ToString());
                });
            }
        }

然而,我不知道如何在不将源代码转换为文本块的情况下找到哪个对象被“点击”。

3 个答案:

答案 0 :(得分:2)

假设您有一个托管所有其他视图的主页/视图,例如主窗口: 我从viewmodels发送一个消息事件,对话框在主窗口后面的代码中处理。这是我项目中唯一的代码隐藏,所以我觉得项目的其余部分可以是严格的MVVM,只有一个例外。

我使用以下内容发送消息(从VB转换,因此可能需要工作):

object message = new DialogMessage("YourMessage", YourFunctionThatHandlesCallback) {
    Button = MessageBoxButton.YesNo,
    Caption = "Caption Goes Here"
};
Messenger.Default.Send(message);

我在后面的主页代码中注册了以下对话框:

Partial Public Class MainWindow
  Inherits Window

  Public Sub New()
    InitializeComponent()

    ''single initialization of messanger for catching message box
    Messenger.[Default].Register(Of DialogMessage)(Me, Sub(msg)
                                                           Dim result = MessageBox.Show(msg.Content, msg.Caption, msg.Button, MessageBoxImage.Warning)
                                                           ''Send callback
                                                           msg.ProcessCallback(result)
                                                       End Sub)
  End Sub
End Class

我无法成功转换C#lambda所以我不得不把它留在VB中。希望这有帮助

答案 1 :(得分:2)

MessageBoxService中有一个Cimbalino Phone Windows Toolkit! 您可以在MVVM架构中使用它。

答案 2 :(得分:1)

遵循“MVVM模式”的真正含义是非常主观的 例如,有些人会说你不应该从VM显示/启动消息箱(任何类型),而其他人会说这很好。

与任何含糊不清一样,您需要平衡对模式的遵守,最适合特定项目的模式,以及适合开发和维护代码库的人员。

就MvvmLight而言,它使用的消息传递系统用于从视图模型到另一个视图模型或视图进行通信,而不是用于向用户显示消息。

如果您要使用Guide.BeginShowMessageBox,尤其是视图模型,请注意它是非阻塞的。如果您希望它的行为类似于“常规”MessageBox,则需要将其与ManualResetEvent一起使用,以便在显示消息框时无法继续与应用互动。