Как реализовать в WPF подтверждение открытия нового файла => несохраненные изменения потеряны? - PullRequest
0 голосов
/ 22 августа 2011

Я реализую приложение с моделью viewviewmodel, у меня есть одно представление, где вы можете изменить все свойства объекта, этот объект является свойством viewmodel из представления. Но у него также есть строка меню, такая как windows, с file => open, new file, save, save as .. Если я нажимаю на новый файл, приложение должно создать новый объект. Работает нормально, поэтому объект сбрасывается. Каждое поле и вещи снова становятся пустыми. Но теперь я хочу реализовать окно подтверждения, потому что если пользователь случайно нажмет на новый файл, он потеряет все. и в этом окне подтверждения у меня есть 2 кнопки, да и нет: да, приложение сбрасывает все значения, но если он нажимает на нет, окно просто закрывается, и пользователь может продолжить работу с текущим объектом. Моя проблема с кнопкой да. Это окно, но метод для создания нового объекта находится в моей viewmodel. Итак, на мой взгляд, модель:

 this.Examination = new Examination();

Без подтверждения я просто перехожу из моего представления к этому методу в модели представления, но теперь, как я могу перейти из окна подтверждения (после нажатия на да) к моей модели представления?

Кто-нибудь, кто может мне помочь, пожалуйста?

Ответы [ 2 ]

2 голосов
/ 22 августа 2011

Создайте команду в вашей модели представления, которая создает новый объект, и привяжите кнопку да к этой команде.

<Button Command="{Binding CreateNewExaminationCommand, Source={x:Static viewmodel:ExaminationViewModel.Instance}}"></Button>

// VIEWMODEL
    RelayCommand createNewExaminationCommand;
    public ICommand CreateNewExaminationCommand
    {
        get
        {
            if (createNewExaminationCommand== null)
            {
                createNewExaminationCommand= new RelayCommand(param => this.CreateNew(),
                    param => this.CanCreateNew);
            }
            return createNewExaminationCommand;
        }
     }

     private ExaminationViewModel() {}

     private static readonly ExaminationViewModel instance = new ExaminationViewModel();
     public static ExaminationViewModel Instance
     {
           get {return instance;}
     }
0 голосов
/ 23 августа 2011

Существует несколько способов решения проблемы.

Самое простое - просто использовать MessageBox.Show в вашей модели представления. Это просто для кода и легко понять. Это также лишает вас возможности модульного тестирования модели представления, поскольку теперь его поведение заключается в блокировании и ожидании ввода пользователя.

Следующим шагом вверх по цепочке сложности является определение интерфейса для моделей представлений, которые необходимо использовать, когда им нужно задать вопрос «да» или «нет». Например:

public interface IConfirmationDialogService
{
   bool Show(string question);
}

Ваша модель представления затем реализует свойство:

public IConfirmationDialogService ConfirmationDialogService { get; set; }

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

public class ViewConfirmationDialogService : IConfirmationDialogService
{
   public string Caption { get; set; }

   public bool Show(string question)
   {
      return MessageBox.Show(
         string question, 
         Caption, 
         MessageBoxButtons.YesNo,
         MessageBoxImage.Question) == MessageBoxResult.Yes;
   }
}

Теперь в любом месте модели просмотра вы можете получить подтверждение от пользователя:

if (!ConfirmationDialogService.Show("Do you want to do this?"))
{
   return;
}

Как вы тестируете это? С издевательством. В ваших модульных тестах вы реализуете класс для имитации пользовательского ввода:

public class MockConfirmationDialogService : IConfirmationDialogService
{
   public MockConfirmationDialogService(bool result)
   {
      _Result = result;
   }

   private bool _Result;

   public bool Show(string question)
   {
      return _Result;
   }
}

, чтобы вы могли протестировать свои методы, ожидающие ввода пользователя, например ::

MyViewModel vm = new MyViewModel()

ConfirmationDialogService = new MockConfirmationDialogService(false);
vm.ExecuteCommand();
Assert.IsFalse(vm.CommandChangedSomething);

vm.ConfirmationDialogService = new MockConfirmationDialogService(true);
vm.ExecuteCommand();
Assert.IsTrue(vm.CommandChangedSomething);

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

...