Tuesday 19 April 2011

How to load and bind Image in MVVM?

I was getting overwhelmed today by a little issue, very little, but enough to waste you several hours, -- the problem is, I have an application  using MVVM, and I have an Image binded to the ViewModel, codes is here:

XAML:

   1:  <Button Height="119" Width="128" BorderBrush="#FFF51B1B" BorderThickness="2" Canvas.Left="413" Command="{Binding ChoosePhotoCommand}" Background="White">
   2:      <Image x:Name="imgPhoto" Source="{Binding MyImage}" />
   3:  </Button>

In the ViewMode, I have a Property MyImage like this:


   1:   Image myImage;
   2:   public Image MyImage
   3:   {
   4:       get { return myImage; }
   5:       set { myImage = value; RaisePropertyChanged("MyImage"); }
   6:   }

The ChoosePhotoCommand Command's code is like this:



   1:  private RelayCommand choosePhotoCommand;
   2:  public RelayCommand ChoosePhotoCommand
   3:  {
   4:      get { return choosePhotoCommand; }
   5:      set
   6:      {
   7:          choosePhotoCommand = value;
   8:          RaisePropertyChanged("ChoosePhotoCommand");
   9:      }
  10:  }

you can see that I am using RelayCommand which is MVVMLight framework, but it's really the same as the normal .net ICommand onject

so in construction, i assign the value for this command, like this:


   1:   public MyViewModel()
   2:   {
   3:       ChoosePhotoCommand = new RelayCommand(choosePhoto, canExecuteChoosePhoto);
   4:   }



   1:  private Image thePhoto = new Image();
   2:  private void choosePhoto()
   3:  {
   4:   
   5:      if (Application.Current.IsRunningOutOfBrowser)
   6:      {
   7:          string path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
   8:          OpenFileDialog ofd = new OpenFileDialog();
   9:          ofd.Filter = "PNG Files (*.png;*.png)|*.png;*.png | All Files (*.*)|*.*";
  10:          ofd.FilterIndex = 1;
  11:   
  12:          if (true == ofd.ShowDialog())
  13:          {
  14:              System.IO.Stream stream = ofd.File.OpenRead();
  15:              BitmapImage bi = new BitmapImage();
  16:              bi.SetSource(stream);
  17:              thePhoto.Source = bi;
  18:              stream.Close();
  19:   
  20:              MyImage = thePhoto;
  21:          }
  22:      }
  23:      else
  24:      {
  25:          MessageBox.Show("please choose photo from disk in Out Of Browser Model");
  26:      }
  27:  }  


OK, now if I select any photo from disk(first you have to make sure you are running in Out of Browser model), the binded Image doesn't change, it keep blank, what's wrong?

the problem is here:

2:      <Image x:Name="imgPhoto" Source="{Binding MyImage}" />

You can't bind an Image's Source property to another Image object, that doesn't make sense, you have to bind the Source to another Source, modify the code like this:

2:      <Image x:Name="imgPhoto" Source="{Binding MyImage.Source}" />
this time, the binding is ok. run the application, and everything is as expected

No comments:

Post a Comment