Как открыть новое окно с помощью MVVM Light Toolkit

Я использую MVVM Light toolkit в своем приложении WPF. Я хотел бы знать, что лучше всего подходит для открытия нового windows из существующего windows. У меня есть этот MainViewModel , который отвечает за MainWindow моего приложения. Теперь в MainView , нажав кнопку, я бы хотел открыть второе окно поверх него. У меня есть RelayCommmand к команде Button . В RelayCommand я могу создать новый объект windows и просто вызвать Show() , что-то вроде этого:

 var view2 = new view2() view2.Show() 

но я не думаю, что ViewModel должен отвечать за создание нового объекта view2 . Я прочитал этот пост WPF MVVM Get Parent из VIEW MODEL, где Bugnion предложил передать сообщение в view1 из viewmodel1 а затем view1 должен создать новый view2 . Но я не уверен, что он на самом деле означает, передавая сообщение view1 ? Как обработать сообщение view1 ? В этом коде или что?

С уважением, Набель

Передача сообщения из ViewModel1 в View1 означает использование возможностей обмена сообщениями в MVVM Light Toolkit .

Например, ваш ViewModel1 может иметь команду ShowView2Command, затем он отправит сообщение для отображения представления.

 public class ViewModel1 : ViewModelBase { public RelayCommand ShowView2Command { private set; get; } public ViewModel1() : base() { ShowView2Command = new RelayCommand(ShowView2CommandExecute); } public void ShowView2CommandExecute() { Messenger.Default.Send(new NotificationMessage("ShowView2")); } } 

View1 будет регистрироваться, чтобы получать сообщения в своем коде позади и отображать View2, когда он получает правильное сообщение.

 public partial class View1 : UserControl { public View1() { InitializeComponent(); Messenger.Default.Register(this, NotificationMessageReceived); } private void NotificationMessageReceived(NotificationMessage msg) { if (msg.Notification == "ShowView2") { var view2 = new view2(); view2.Show(); } } } 

Почему вы идете по этому маршруту? Это просто. Если вы замените свою кнопку на toggleButton или на гиперссылку или на любое другое количество кнопочных элементов управления, вам не нужно обновлять свой «код позади» – это основной принцип шаблона MVVM. В вашем новом toggleButton (или что-то еще) вы все равно ввязываетесь в одну и ту же точную команду.

Например, я создаю проект для клиента, который хочет иметь 2 пользовательских интерфейса – один из них будет принципиально отличаться во всех отношениях, с точки зрения презентации. Горизонтальные вкладки против вертикального RadPanelBar (думаю, Аккордеон) для навигации. Оба эти представления могут указывать на один и тот же viewModel – когда пользователь нажимает вкладку «Рабочий заказ» в представлении 1, он запускает тот же «WorkOrderCommand», который запускается в заголовке рабочего заказа на панели панели.

В модели с кодовым кодом вам придется закодировать два отдельных события. Здесь вам нужно только ввести код.

Кроме того, он позволяет дизайнеру с помощью Blend создавать любой макет, который они хотят. Пока у них есть крючки (EventToCommand control) на месте, мне (как разработчику) все равно, как выглядит конечный продукт.

Свободная муфта невероятно мощная.

Вы можете сделать это так, как вам нужно создать некоторые события и зарегистрировать их в представлении и вызвать их в виде model.and открыть это всплывающее окно.

Как этот пример

 public class Mainclass : MainView { public delegate abc RegisterPopUp(abc A); public RegisterPopUp POpUpEvent ; public RelayCommand ShowCommand { private set; get; } public void ShowCommand() { ShowCommand("Your parameter"); } } 

внутри представления MainView mn=new MainView();

Зарегистрируйте событие здесь, например thake mn.POpUpEvent += чем дважды нажмите кнопку вкладки

и в регистре всплывающего метода правильно код для открытия всплывающего windows.

Если я не пропущу здесь смысла – если бы я использовал код позади, то почему бы прямо не реализовать событие button_click и открыть второе представление?

Кажется, что Bugnion предлагает: view1 -> кнопка click -> команда relay -> viewmodel1 -> message -> view1 -> view1.cs -> open view 2.

Вы все равно будете жертвовать тестируемостью, написав код, поэтому зачем брать такой длинный маршрут?

Вы можете абстрагировать определенные функции просмотра в сервисах, используя общий интерфейс. На уровне представления вы можете предоставить конкретные экземпляры этих сервисов и построить модели представления с использованием контейнера IoC и метода впрыскивания зависимостей.

В вашем случае вы можете построить интерфейс IWindowManager или что-то подобное, которое имеет необходимый метод. Это можно применить к вашему слою представления. Недавно я написал небольшое сообщение в блоге, в котором показано, как абстрагироваться от поведения диалогового поведения вне модели. Подобный apporach может использоваться для любого связанного с пользовательским интерфейсом сервиса, такого как Навигация, MessageBoxes и т. Д.

Эта ссылка может быть полезна для вас http://nileshgule.blogspot.com/2011/05/silverlight-use-dialogservice-to.html

Многие люди также используют подход для запуска событий из моделей просмотра, которые подписаны на файл view.cs, и оттуда выполняется MessageBox или любое другое действие, связанное с пользовательским интерфейсом. Мне лично нравится подход к инъекционным услугам, потому что тогда вы можете предоставить несколько реализаций одной и той же услуги. Простым примером может быть то, как навигацию обрабатывают в приложениях Silverlight и Windows Phone 7. Вы можете использовать одну и ту же модель представления, но вводить различные реализации службы навигации на основе типа приложения.

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

  1. Создать class DialogCloser
     открытый статический class DialogCloser
     {
         public static readonly DependencyProperty DialogResultProperty = DependencyProperty.RegisterAttached («DialogResult», typeof (bool?), typeof (DialogCloser), новый PropertyMetadata (DialogResultChanged));

         private static void DialogResultChanged (DependencyObject d, DependencyPropertyChangedEventArgs e)
         {
             var window = d as Window;
             if (window! = null) window.Close ();
         }

         public static void SetDialogResult (objective windows, значение bool?)
         {
             target.SetValue (DialogResultProperty, значение);
         }
     }
  1. Создайте Base ViewModel, наследующий от GalaSoft.MvvmLight.ViewModelBase с дополнительными членами. После этого используйте эту модель представления в качестве базы для других режимов просмотра.
     BOOL?  _closeWindowFlag;
     общественный bool?  CloseWindowFlag
     {
         get {return _closeWindowFlag;  }
         задавать
         {
             _closeWindowFlag = значение;
             RaisePropertyChanged ( "CloseWindowFlag");
         }
     }

     public virtual void CloseWindow (bool? result = true)
     {
         Application.Current.Dispatcher.BeginInvoke (DispatcherPriority.Background, 
         new Action (() =>
         {
             CloseWindowFlag = CloseWindowFlag == null?  true:! CloseWindowFlag;
         }));
     } 
  1. В представлении DialogCloser.DialogResult свойство зависимостей DialogCloser.DialogResult с свойством CloseWindowFlag в базовой модели представления.

Затем вы можете открыть / закрыть / скрыть окно из viewmodel.

  • Для чего нужен DataContext?
  • Ширина столбца DataGrid не обновляется автоматически
  • Использование MediaElement для воспроизведения видео из Stream
  • Binding ElementName. Использует ли это Визуальное дерево или Логическое дерево
  • ItemPropertyChanged не работает на наблюдаемомколлекции.Почему?
  • Как отключить цвет фона в TextBox в WPF
  • Назначить BitmapImage из Resource.resx в Image.Source?
  • Как показать прогресс во время цикла занятости?
  • Как узнать, какой монитор находится в окне WPF?
  • Введите ключевой обработчик события
  • Найти элемент WPF внутри DataTemplate в коде
  • Давайте будем гением компьютера.