2013-03-14 2 views
2

Я делаю Windows 7 телефона и пытаюсь сделать это с помощью MVVM. Я бы хотел, чтобы модель моего представления была максимально чистой, но я не уверен, как сделать диалоговое окно. Я использую свет MVVM, и я знаю, что у них есть система обмена сообщениями или что-то еще, но не совсем уверен, как ее использовать.Как обращаться с диалоговыми окнами MessageBox при использовании шаблона MVVM (MVVM Light ToolKit)

Я хотел бы использовать Guide.BeginShowMessageBox, поскольку это, кажется, дает больше возможностей, чем стандартное диалоговое окно.

Как это сделать, не нарушая шаблон MVVM. AS, когда я загружаю представление, я хочу запустить триггер загрузки, а затем проверить некоторые условия. Если условия выполнены, отобразите диалоговое окно.

// 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> 

Edit Другая проблема я имею. У меня есть список, который связан с некоторыми данными, которые хранятся в этом свойстве

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()); 
       }); 
      } 
     } 

Но я не знаю, как найти который был «постучал», не подвергая источник текстовому блоку.

+0

Какой у вас вопрос? –

+0

Обновлен мой вопрос, чтобы было ясно. Также добавлен код, с которым я пытался работать. – chobo2

ответ

1

Что действительно означает следовать «шаблону MVVM», это очень субъективная вещь.
Например, некоторые люди скажут, что вы не должны показывать/запускать из ВМ сообщение (любого типа), в то время как другие скажут, что это нормально.

Как и любая двусмысленность, вам необходимо сбалансировать приверженность шаблону, с тем, что наиболее подходит для конкретного проекта, с тем, что подходит для людей, разрабатывающих и поддерживающих базу кода.

Что касается MvvmLight, то система обмена сообщениями, которую он использует, предназначена для связи с моделью просмотра или с другой моделью просмотра или с представлением, а не для отображения сообщений пользователю.

Если вы собираетесь использовать Guide.BeginShowMessageBox, в частности, из режима просмотра, остерегайтесь, чтобы он не блокировался. Если вы хотите, чтобы он вел себя как «обычный» MessageBox, вам нужно использовать его с ManualResetEvent, так что невозможно продолжить взаимодействие с приложением, пока отображается сообщение.

+0

Я вот что думаю с шаблоном MVVM, какое усилие вознаградить. Я имею в виду, что иногда проще и чище делать это одним способом и не может быть на 100% правильным, чем писать тонны кода и затруднять чтение. Если я, где делать MVVM, как вы это делаете? – chobo2

+0

@ chobo2 нет «одного способа MVVM», чтобы показать сообщение. Если вы хотите быть как можно более «чистым»: введите службу в модель просмотра, которая может отображать окно сообщения, а затем вызовите эту службу, чтобы показать окно сообщения, когда это необходимо. –

+0

Хмм мне кажется странным, что, когда я думаю о сервисах, я думаю о слоях услуг, которые должны быть как можно более чистыми, а также не иметь такого кода в нем, но это касается веб-приложений. Поэтому каждый раз, когда мне нужно что-то делать на виртуальной машине, мне нужно использовать сервис? Как насчет в этом случае? У меня есть жест (RelayCommand), и я хочу найти его исходный var selectedTextBlock = e.OriginalSource как TextBlock; Должен ли я переместить эту линию на службу и передать в e? – chobo2

2

Предполагая, что у вас есть одна главная страница/просмотр, на которой размещены все другие виды, например mainwindow: Я отправляю событие сообщения из режимов просмотра, а диалоговое окно обрабатывается в коде позади главного окна. Это единственный код, который у меня есть в моем проекте, поэтому я считаю приемлемым, что остальная часть проекта может быть строго 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#, поэтому мне пришлось оставить его в VB. Надеюсь, это поможет

Смежные вопросы