Björn
Björn

Reputation: 3418

Handling null when binding to an Image in XAML

I have an Image element in XAML. I bind the Source property to a string property in my ViewModel. However, sometimes the value is null and then I get errors in the debug window.

I read here: ImageSourceConverter error for Source=null that I could make a converter to return DependencyProperty.UnsetValue if the value is null.

Now I'm wondering if it is possible to do it directly in XAML? Perhaps by using a FallbackValue? I have tried some variants but with no luck.

This is my Image element in XAML:

<Image Name="img" Source="{Binding Path=CurrentImageSource}" Stretch="None" />

And CurrentImageSource is just a string property on the DataContext.

The error message is: System.Windows.Data Error: 23 :

Cannot convert '' from type '' to type 'System.Windows.Media.ImageSource' for 'sv-SE' culture with default conversions; consider using Converter property of Binding. NotSupportedException:'System.NotSupportedException: ImageSourceConverter cannot convert from (null).

Upvotes: 30

Views: 25842

Answers (5)

camios
camios

Reputation: 342

Assuming the source is a Uri, I had this problem too when the Image control is about to be unloaded. For some reason the Image's Source was being set to null by the Presentation framework. The ImageSourceConverter didn't know how to convert a null to a concrete ImageSource instance (ImageSource is abstract). That's why using TargetNulValue={x:Null} in the binding works - if Source is null it doesn't try to convert to an ImageSource.

Another option, instead of setting the Source property on the Image, use an explicit BitmapImageSource and set its UriSource.

<Image Name="img" Stretch="None">
  <Image.Source>
    <BitmapImage UriSource="{Binding Path=CurrentImageSource}"/>
  </Image.Source>
</Image>

Upvotes: 0

leo5th
leo5th

Reputation: 41

I just check the answer of Sascha Hennig. It runs well on my side. I just have a little modification on my side (remove /ImageNullRef; in image resource) <BitmapImage x:Key='defaultImage' UriSource='component/errorImage.png' />

Upvotes: 0

flobadob
flobadob

Reputation: 2872

I used x:Null with TargetNullValue, that way you get an easy blank image...

<Image Source="{Binding LogoPath, TargetNullValue={x:Null}}" />

That way you don't need to mess around with Triggers or BitmapImages as static resources.

Upvotes: 81

Sascha Hennig
Sascha Hennig

Reputation: 2572

You can check for a null reference using a data trigger:

<Image Name="img" Stretch="None" >
    <Image.Style>
        <Style TargetType="{x:Type Image}">
            <Setter Property="Source" Value="{Binding CurrentImageSource}" /> 
            <Style.Triggers>
                <DataTrigger Binding="{Binding CurrentImageSource}" Value="{x:Null}">
                    <Setter Property="Source" Value="/ImageNullRef;component/errorImage.png" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Image.Style>
</Image>

Whilst it is not possible to test directly whether two values differ, you can see whether a value is greater or smaller, etc. using this approach Mike Hillberg blogged about.

Upvotes: 22

mbursill
mbursill

Reputation: 3151

I haven't tested it, but I think this is what TargetNullValue is for:

<Image Name="img" Source="{Binding Path=CurrentImageSource, TargetNullValue=/ImageNullRef;component/errorImage.png}" Stretch="None" />

Upvotes: 19

Related Questions