WPF & MVVM: обновить поле изображения, не нарушая шаблон - PullRequest
4 голосов
/ 12 февраля 2011

В настоящее время я учусь писать приложение WPF с использованием шаблона MVVM. Я пишу небольшое приложение диспетчера контактов, поэтому мое приложение отображает Listbox, привязанный к моей View Model, и набор полей, привязанных к ListBox.SelectedItem. Одним из этих полей является фотография контакта.

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

Сначала я попытался обновить свойство источника элемента управления Image, но при этом я теряю привязку ... Затем я написал обработчик Button_Click для обновления свойства Contact.Photo (его тип byte []), и он работает. Но вместо привязки «элемента управления обновлениями» к модели представления привязка осуществляется от виртуальной машины к элементу управления, как если бы данные поступали из БД.

(В коде LoadPhoto возвращает байт [])

private void Button_Click(object sender, RoutedEventArgs e)
{
    OpenFileDialog OpenFileDialog = new OpenFileDialog();
    if (OpenFileDialog.ShowDialog() == true)
    {
        (listbox.SelectedItem as ContactManager.ViewModel.Contact).Photo = 
                LoadPhoto(OpenFileDialog.FileName);
    }
}

Интересно, не нарушает ли это шаблон MVVM ... Я не уверен в том, что можно сделать в представлении ... Это правильный способ обновления объекта Contact? У кого-нибудь есть лучшее решение этой проблемы?

1 Ответ

2 голосов
/ 12 февраля 2011

Изучите привязку вашей кнопки к привязке команд вместо события щелчка.
Вы можете найти реализации DelegateCommand с помощью Google.
Затем вы можете предоставить ImageSource из вашей ViewModel, которую вы можете привязать к своему Image из вашего XAML.

Я включил несколько фрагментов кода, чтобы начать работу.

Как только вы ознакомитесь с основами, взгляните на MVVM Frameworks, например Cinch , вы найдете способ обработки OpenFileDialog с помощью Интерфейсы служб IOpenFileService.cs, чтобы не нарушать шаблон MVVM.

Вот XAML:

  <Button Content="Update Photo" Command="{Binding UpdatePictureCommand}"/>

  <Image Source="{Binding EmployeePicture}"
                   VerticalAlignment="Center" HorizontalAlignment="Center"
                   Stretch="Fill" />

Вот ViewModel:

  public MainViewModel()
  {
     UpdatePictureCommand = new DelegateCommand<object>(OnUpdatePictureCommand, CanUpdatePictureCommand);
  }

  public ICommand UpdatePictureCommand { get; private set; }
  private void OnUpdatePictureCommand(object obj)
  {
    OpenFileDialog OpenFileDialog = new OpenFileDialog();
   if (OpenFileDialog.ShowDialog() == true)
   {
     //(listbox.SelectedItem as ContactManager.ViewModel.Contact).Photo = 
     //    LoadPhoto(OpenFileDialog.FileName);
     Stream reader = File.OpenRead(OpenFileDialog.FileName);
     System.Drawing.Image photo = System.Drawing.Image.FromStream((Stream)reader);

     MemoryStream finalStream = new MemoryStream();
     photo.Save(finalStream, ImageFormat.Png);

     // translate to image source
     PngBitmapDecoder decoder = new PngBitmapDecoder(finalStream, BitmapCreateOptions.PreservePixelFormat,
                                         BitmapCacheOption.Default);
     EmployeePicture =  decoder.Frames[0];;
  }

  private bool CanMoveFirstCommand(object obj)
  {
     return true;
  }

  private ImageSource _employeePicture;
  public ImageSource EmployeePicture
  {
     get
     {
        return _employeePicture;
     }
     set
     {
        _employeePicture = value;
        OnPropertyChanged("EmployeePicture");
     }
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...