Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding an Image in WPF MVVM

Tags:

c#

mvvm

wpf

I am having some trouble binding in Image to my viewmodel. I finally got rid of the XamlParseException, but the image does not come up. I even hard coded the image in the ViewModel. Can someone see what I am doing wrong?

View:

<Image HorizontalAlignment="Left" Margin="0,0,0,0" Name="image1" Stretch="Fill" VerticalAlignment="Bottom" Grid.Row="8" Width="200"  Grid.ColumnSpan="2" > <Image.Source>     <BitmapImage DecodePixelWidth="200" UriSource="{Binding Path=DisplayedImage, Mode=TwoWay}" /> </Image.Source> 

ViewModel:

 string _DisplayedImagePath = @"C:\Users\Public\Pictures\Sample Pictures\Chrysanthemum.jpg";//string.Empty;     int _DisplayedImageIndex;     BitmapImage _DisplayedImage = null;     public BitmapImage DisplayedImage     {         get         {             _DisplayedImage = new BitmapImage();             if (!string.IsNullOrEmpty(_DisplayedImagePath))             {                 _Rail1DisplayedImage.BeginInit();                 _Rail1DisplayedImage.CacheOption = BitmapCacheOption.OnLoad;                 _Rail1DisplayedImage.CreateOptions = BitmapCreateOptions.IgnoreImageCache;                 _Rail1DisplayedImage.UriSource = new Uri(_DisplayedImagePath);                 _Rail1DisplayedImage.DecodePixelWidth = 200;                 _Rail1DisplayedImage.EndInit();             }             return _Rail1DisplayedImage;         }         set         {             _Rail1DisplayedImage = value;             OnPropertyChanged("DisplayedImage");         }     } 
like image 346
kurgaan Avatar asked Feb 14 '14 20:02

kurgaan


People also ask

How do I bind Mvvm?

MVVM – WPF Data Bindings For data binding you need to have a view or set of UI elements constructed, and then you need some other object that the bindings are going to point to. The UI elements in a view are bound to the properties which are exposed by the ViewModel.

What is binding in WPF?

Data binding is a mechanism in WPF applications that provides a simple and easy way for Windows Runtime apps to display and interact with data. In this mechanism, the management of data is entirely separated from the way data. Data binding allows the flow of data between UI elements and data object on user interface.

What is oneway binding WPF?

In One Way binding, source control updates the target control, which means if you change the value of the source control, it will update the value of the target control. So, in our example, if we change the value of the slider control, it will update the textbox value, as shown below.


2 Answers

Displaying an Image in WPF is much easier than that. Try this:

<Image Source="{Binding DisplayedImagePath}" HorizontalAlignment="Left"      Margin="0,0,0,0" Name="image1" Stretch="Fill" VerticalAlignment="Bottom"      Grid.Row="8" Width="200"  Grid.ColumnSpan="2" /> 

And the property can just be a string:

public string DisplayedImage  {     get { return @"C:\Users\Public\Pictures\Sample Pictures\Chrysanthemum.jpg"; } } 

Although you really should add your images to a folder named Images in the root of your project and set their Build Action to Resource in the Properties Window in Visual Studio... you could then access them using this format:

public string DisplayedImage  {     get { return "/AssemblyName;component/Images/ImageName.jpg"; } } 

UPDATE >>>

As a final tip... if you ever have a problem with a control not working as expected, simply type 'WPF', the name of that control and then the word 'class' into a search engine. In this case, you would have typed 'WPF Image Class'. The top result will always be MSDN and if you click on the link, you'll find out all about that control and most pages have code examples as well.


UPDATE 2 >>>

If you followed the examples from the link to MSDN and it's not working, then your problem is not the Image control. Using the string property that I suggested, try this:

<StackPanel>     <Image Source="{Binding DisplayedImagePath}" />     <TextBlock Text="{Binding DisplayedImagePath}" /> </StackPanel> 

If you can't see the file path in the TextBlock, then you probably haven't set your DataContext to the instance of your view model. If you can see the text, then the problem is with your file path.


UPDATE 3 >>>

In .NET 4, the above Image.Source values would work. However, Microsoft made some horrible changes in .NET 4.5 that broke many different things and so in .NET 4.5, you'd need to use the full pack path like this:

<Image Source="pack://application:,,,/AssemblyName;component/Images/image_to_use.png"> 

For further information on pack URIs, please see the Pack URIs in WPF page on Microsoft Docs.

like image 157
Sheridan Avatar answered Sep 23 '22 12:09

Sheridan


@Sheridan thx.. if I try your example with "DisplayedImagePath" on both sides, it works with absolute path as you show.

As for the relative paths, this is how I always connect relative paths, I first include the subdirectory (!) and the image file in my project.. then I use ~ character to denote the bin-path..

    public string DisplayedImagePath     {         get { return @"~\..\images\osc.png"; }     } 

This was tested, see below my Solution Explorer in VS2015..

example of image binding in VS2015)

Note: if you want a Click event, use the Button tag around the image,

<Button Click="image_Click" Width="128" Height="128"  Grid.Row="2" VerticalAlignment="Top" HorizontalAlignment="Left">    <Image x:Name="image" Source="{Binding DisplayedImagePath}" Margin="0,0,0,0" />  </Button>
like image 22
Goodies Avatar answered Sep 20 '22 12:09

Goodies