简体   繁体   中英

How to bind the Image.Source in MVVM correctly?

I spent some time now trying to work this out but I am still stuck on it. I have a WPF application with a MVVM pattern. In my ViewModel I have three cases where:

  • X needs Y and Y is available
  • X needs Y and Y is not available
  • X doesn't need Y

I am trying to set an image icon on my view based on these conditions (Like a Check Mark, exclamation Mark... whatever).

In ViewModel: I created my properties. On any GUI change, I set the variables based on the above cases similar to the following:

void MyBigFunctionToSetAllProperties()
{
   // other cases
   // ..
   if (NeedsY && YExists)
    {
        // properties
        StatusIconPath = "@\"/Resources/SessionView/X-With-Green-Check-White.png\"";
        ResultIconPath = "@\"/Resources/SessionView/Y-White.png\"";
    }
}

In View.Cs : I did literally nothing.

In View.xaml: I bind like this:

<StackPanel>
     <Image Source="{Binding StatusIconPath} />
</StackPanel>

I still can't see why it is not working. What is that thing that I am missing? Please and thanks.

It did not work to bind the properties directly with the Xaml as recommended. I tried it this way:

VM: sample property:

public BitmapImage VerificationStatusIcon{ get { return new BitmapImage(new Uri(@VerificationStatusIconPath, UriKind.Relative));}}

View Xaml :

<Image Name="verificationStatusImage" Source="{Binding VerificationStatusIcon}" Margin="5,0" Width="40" Height="40"/>

You have a whole bunch of unnecessary characters in your icon paths:

StatusIconPath = "@\"/Resources/SessionView/X-With-Green-Check-White.png\"";
ResultIconPath = "@\"/Resources/SessionView/Y-White.png\"";

Change them to this:

StatusIconPath = "Resources/SessionView/X-With-Green-Check-White.png";
ResultIconPath = "Resources/SessionView/Y-White.png";

. But no images originally to view and no changes..

Verify that the path to the image is correct. Maybe hard code an image to test the control against it.

One other scenario is that the resources are not being copied over for run-time acquisition. Make sure they are actually available during runtime.

can't see why it is not working

Is the main view's DataContext set to the live VM's instance?

What is that thing that I am missing?

If you are sure that the view's datacontext contains the live VM, then make sure that the property StatusIconPath on the VM reports a property change event .

That is so that the XAML control which is bound to it knows that it changed and correspondingly one needs to make sure that the ViewModel which holds StatusIconPath adheres to INotifyPropertyChanged which will facilitate such an operation in general:

private string _StatusIconPath;

public string StatusIconPath 
{
   get { return _StatusIconPath; }
   set
       {
       _StatusIconPath = value;
       PropertyChanged("StatusIconPath");
       }
}

I provide more robust example on my blog entitled:

Xaml: ViewModel Main Page Instantiation and Loading Strategy for Easier Binding

It turned out that I have an extra unneeded characters in my ImagePaths as Kyle stated. And then, I needed to set my Image.Source from within my View.cs . At least, this is how it worked for me:

ViewModel Something like this:

if (Whatever)
{
    StatusIconPath = "/Resources/SessionView/X-With-Green-Check-White.png";
    ResultIconPath = "/Resources/SessionView/Y-White.png";
}

Then in View.cs and on SelectedItemChanged :

private void Grid_SelectedItemChanged(object sender, DevExpress.Xpf.Grid.SelectedItemChangedEventArgs e)
{
    string tempStatus = ((SessionViewModel) DataContext).StatusIconPath;
    string tempResult = ((SessionViewModel) DataContext).ResultIconPath;
    StatusImage.Source = new BitmapImage(new Uri(@tempStatus, UriKind.Relative));
    ResultImage.Source = new BitmapImage(new Uri(@tempResult, UriKind.Relative));
}

and in Xaml: just a fallback value(any original/default image we want). Ex:

<Image Name="ResultImage" Source="/EZ3D;component/Resources/SessionView/Retake-White.png"/>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM