Как создать диалоговое окно и записать пользовательский ввод, в то время как шаблон MVVM используется для создания диалога в WPF - PullRequest
0 голосов
/ 27 июня 2019

Я разработчик на C ++ и новичок в WPF и MVVM. пожалуйста, потерпите меня, если я выберу неправильное слово, чтобы задать свой вопрос

У меня есть основное приложение в MFC / C ++ , которое передает некоторые данные в библиотеку C # ( CLI используется в качестве среднего уровня). В библиотеке C # есть раздел кода, в котором открывается диалоговое окно, заполняются данные и пользовательский выбор уведомляется вызывающему объекту следующим образом -

public classA()
{
    MyDialog dlg = new MyDialog(param1, param2, param3)
    if(dlg.ShowDialog().GetValueOrDefault())
    {
        var name = dlg.name;
        var roll = dlg.roll;
    }
    else
    {
        var name = string.Empty;
        var roll = string.Empty;
    }
}

Теперь диалог был изменен и реализован с использованием шаблона MVVM .

Я создал следующие файлы как часть реализации 1

  1. MyDialogView.Xaml
  2. MyDialogView.xaml.cs
  3. MyDialogViewModel.cs
  4. MyDialogModel.cs

Мой вопрос заключается в том, как создать экземпляр нового диалогового окна из моего classA , чтобы данные заполнялись с использованием параметров, переданных в диалоговое окно, так же, как это делалось ранее, и записывали выбор пользователя без потери каких-либо данных. и безопасно закрываем вид.

Ответы [ 2 ]

2 голосов
/ 27 июня 2019

Стандартный подход MVVM работает следующим образом (по крайней мере, при использовании MVVM Light):

  1. У вас есть слой VM, библиотека классов.
  2. У вас есть слой View, библиотека элементов управления WPF или приложение WPF.
  3. Просмотр слоя добавляет ссылку на слой VM. Слой VM ничего не знает о View.
  4. Вы создаете обычный публичный класс для виртуальной машины вашего диалога. Назовите это DialogVM или как угодно. Убедитесь, что этот класс наследует от встроенного в MVVM Light ViewModelBase. Это позволит вам получить доступ к способам уведомления об изменениях, предоставляемым MVVM Light. Может выглядеть так в вашем случае:

    public partial class DialogVM : ViewModelBase
    {
        private string _Name;
        public string Name
        {
          get { return _Name; }
          set { Set(ref _Name, value); }
        }
    
        private string _Roll;
        public string Roll
        {
          get { return _Roll; }
          set { Set(ref _Roll, value); }
        }
    }
    
  5. Уровень VM имеет глобальный статический класс с именем ViewModelLocator. Этот класс выполняет IoC / DI и предоставляет общедоступные статические свойства для отображения разных виртуальных машин. (В вашем случае виртуальная машина вашего диалога переходит в проект виртуальной машины, и ViewModelLocator выглядит примерно так:

    using System;
    
    namespace VMLayer
    {
      public class ViewModelLocator
      {
        static ViewModelLocator()
        {
          SimpleIoc.Default.Register<DialogVM>(true);
        }
    
        public static DialogVM MyDialog => SimpleIoc.Default.GetInstance<DialogVM>();
      }
    }
    
  6. Ваше диалоговое окно (a Window) переходит на слой View и использует это открытое свойство MyDialog, чтобы предоставить DataContext для диалогового окна:

    <Window x:Class="GlasshouseTestingShell.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:vm="clr-namespace:VMLayer;assembly=VMLayer"
        DataContext="{x:Static vm:ViewModelLocator.MyDialog}"
        d:DataContext="{d:DesignInstance Type=vm:DialogVM}">
    </Window>
    
  7. Посмотрите, как чисто мы создали DataContext слоя View без записи строки кода C # в слое View. Это также элегантно в том смысле, что вы получаете все Intellisense времени разработки в Binding выражениях и в других местах.
  8. Теперь вы привязываете все свои элементы пользовательского интерфейса (текстовые поля, кнопки и т. Д.) К общим свойствам и командам, предоставляемым виртуальной машиной вашего диалога. Все еще нет строк в коде позади. Может выглядеть так в вашем случае:

    <TextBox Text="{Binding Name}" />
    

Все остальное в C ++:

  1. Вы добавляете ссылку на свои библиотеки DLL View и VM в своем проекте C ++.
  2. Создайте объект вашего диалога. Он автоматически создаст экземпляр своей виртуальной машины и выполнит связывание. Вы звоните ShowDialog(), чтобы вывести его на экран.
  3. Использование выполняет действия в диалоговом окне и, наконец, нажимает кнопку ОК или Отмена.
  4. Вы фиксируете результат диалога, а затем получаете доступ к свойству DataContext объекта диалога, которое является объектом класса DialogVM. Вы можете получить доступ к предоставленным пользователем значениям, поскольку Binding обновил эти свойства для вас в ВМ.
1 голос
/ 27 июня 2019

Я не уверен, что выполняю все ваши требования, но примерно так я бы подошел к такой задаче:

Создание представления и модели представления в классе А.

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

Установить текстовый вид представления для модели представления.

Все, что вам нужно связать, должно связываться между ними.

Показать диалог просмотра.

Пользователь редактирует представление и сохраняет его в свойствах модели представления.

Они заканчивают редактирование, и вы затем работаете со свойствами viewmodel. Возможно, одна из них - модель, которую вы упоминаете. Может быть, модель создается экземпляром модели для получения данных или классом A, если это более удобно. В последнем случае вам, вероятно, придется передать эту модель модели представления.

Учитывая вышесказанное.

Немного приблизительный код:

public class ClassA
{
    MyDialogViewModel vm = new MyDialogViewModel { Name = "X", Roll = "Y" };
    MyDialog dlg = new MyDialog();
    dlg.ShowDialog();
    var name = vm.Name;
    var roll = vm.roll;

    // Do something to persist your data as necessary. Either here or in a model within the viewmodel
}

Name и Roll предположительно связываются с некоторыми текстовыми полями. Свойства текста в представлении или некоторые другие.

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

MyDialogViewModel должен реализовывать inotifypropertychanged, и все, что вам нужно связать, должно быть публичным свойством. Не уверен, что вам понадобится уведомление об изменении собственности, но всегда применяйте его. При желании поднять свойство изменилось из установщиков свойств.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...