ImageSourceConverter error for Source=null

.NetWpfImageException HandlingIvalueconverter

.Net Problem Overview


I'm binding the Source property of an Image to a string. This string may be null in which case I just don't want to display an Image. However, I'm getting the following in my Debug output:

> System.Windows.Data Error: 23 : Cannot > convert '<null>' from type '<null>' to > type > 'System.Windows.Media.ImageSource' for > 'en-AU' culture with default > conversions; consider using Converter > property of Binding. > NotSupportedException:'System.NotSupportedException: > ImageSourceConverter cannot convert > from (null). at > System.ComponentModel.TypeConverter.GetConvertFromException(Object > value) at > System.Windows.Media.ImageSourceConverter.ConvertFrom(ITypeDescriptorContext > context, CultureInfo culture, Object > value) at > MS.Internal.Data.DefaultValueConverter.ConvertHelper(Object > o, Type destinationType, > DependencyObject targetElement, > CultureInfo culture, Boolean > isForward)'

I'd prefer if this wasn't displayed as it's just noise - is there any way to suppress it?

.Net Solutions


Solution 1 - .Net

@AresAvatar is right in suggesting you use a ValueConverter, but that implementation does not help the situation. This does:

public class NullImageConverter :IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null)
            return DependencyProperty.UnsetValue;
        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        // According to https://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter.convertback(v=vs.110).aspx#Anchor_1
        // (kudos Scott Chamberlain), if you do not support a conversion 
        // back you should return a Binding.DoNothing or a 
        // DependencyProperty.UnsetValue
        return Binding.DoNothing;
        // Original code:
        // throw new NotImplementedException();
    }
}

Returning DependencyProperty.UnsetValue also addresses the performance issues from throwing (and ignoring) all those exceptions. Returning a new BitmapSource(uri) would also get rid of the exceptions, but there is still a performance hit (and it isn't necessary).

Of course, you'll also need the plumbing:

In resources:

<local:NullImageConverter x:Key="nullImageConverter"/>

Your image:

<Image Source="{Binding Path=ImagePath, Converter={StaticResource nullImageConverter}}"/>

Solution 2 - .Net

I used Pat's ValueConverter technique and it worked great. I also tried the TargetNullValue technique, by flobodob from here, and it also works great. It's easier and cleaner.

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

TargetNullValue is simpler, and requires no converter.

Solution 3 - .Net

Bind your image directly on an object and return "UnsetValue" if necessary

<Image x:Name="Logo" Source="{Binding ImagePath}"  />

The property in your ViewModel :

    private string _imagePath = string.Empty;
    public object ImagePath 
    {
        get
        {
            if (string.IsNullOrEmpty(_imagePath))
                return DependencyProperty.UnsetValue;

            return _imagePath;
        }
        set
        {
            if (!(value is string)) 
                return;

            _imagePath = value.ToString();
            OnPropertyChanged("ImagePath");
        }
    }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKai GView Question on Stackoverflow
Solution 1 - .NetPatView Answer on Stackoverflow
Solution 2 - .NetMiyamoto MusashiView Answer on Stackoverflow
Solution 3 - .Netscrat789View Answer on Stackoverflow