WPF and MVVM: update the image field without breaking the template

I am currently learning how to write a WPF application using the MVVM pattern. I am writing a small contact manager application, so my application displays a list attached to my view model and a set of fields related to ListBox.SelectedItem. One of these fields is contact photo.

I want to change the photo in the editing part using OpenFileDialog, so the Listbox element will be updated, as for all other fields.

At first I tried to update the source property of the Image control, but I lose the binding ... Then I wrote a Button_Click handler to update the Contact.Photo property (its type iste []), and it works. But instead of binding from the "update control" to the view model, binding from the VM to the control is as if the data were coming from the database.

(In the code LoadPhoto returns byte [])

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

I wonder if the MVVM pattern does not violate ... I'm not sure what can be done in the view ... Is it correct to change the Contact object? Does anyone have a better solution to this problem?

+4
source share
1 answer

Look at the binding of your button to the binding of commands instead of the click event.
You can find DelegateCommand implementations using Google.
You can then open the ImageSource from the ViewModel, which you can bind to your image from your XAML.

I have included some code snippets to get you started.

Once you have finished the basics, take a look at the MVVM Framework, such as Cinch , you will find a way to handle OpenFileDialog using the IOpenFileService.cs Service Interfaces so as not to violate the MVVM pattern.

Here is the XAML:

  <Button Content="Update Photo" Command="{Binding UpdatePictureCommand}"/> <Image Source="{Binding EmployeePicture}" VerticalAlignment="Center" HorizontalAlignment="Center" Stretch="Fill" /> 

Here is the ViewModel model:

  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"); } } 
+2
source

Source: https://habr.com/ru/post/1339478/


All Articles