ImageSourceConverter错误,源为null。

60

我正在将Image的Source属性绑定到一个字符串。如果该字符串为空,我只是不想显示图像。但是,在我的调试输出中,我得到了以下内容:

System.Windows.Data Error: 23 : 无法将“<null>”从类型“<null>”转换为“System.Windows.Media.ImageSource”的类型,对于默认转换和“en-AU”区域性考虑使用Binding的Converter属性。NotSupportedException: 'System.NotSupportedException: ImageSourceConverter无法从(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)'。

我希望这不会被显示出来,因为它只是噪音 - 有没有办法抑制它?


5
我不确定它只是噪声。在我的应用程序中,我认为这导致了性能问题(当加载所有空图像时)。 - Pat
1
是的,它肯定会导致性能问题。有关详细信息,请参阅我的答案。 - Pat
3个回答

103

@AresAvatar 的建议是正确的,他建议使用一种 ValueConverter ,但该实现并没有帮助解决问题。以下实现可以解决:

@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();
    }
}

返回DependencyProperty.UnsetValue也解决了抛出(和忽略)所有这些异常的性能问题。返回一个new BitmapSource(uri)将也可以消除异常,但仍会有性能损失(而且并不必要)。

当然,你还需要做好接口:

在资源中:

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

你的图片:

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

4
惊奇于我现在考虑图像源的空值时代码运行得更快了。谢谢您的帮助,不过如果“value”是一个字符串,我建议还要处理“string.IsNullOrWhitespace”情况。 - Andrew Garrison
3
在绑定中,是否有一种方法可以将DependencyProperty.UnsetValue指定为TargetNullValue?这可能会消除需要使用转换器的必要性。 - Nitesh
1
我已经进行了非常成功的测试:TargetNullValue={x:Static DependencyProperty.UnsetValue} 注意:如果它是一个空字符串,它将不起作用。如果您正在像在getter中构建字符串路径这样的操作,则可能的一种解决方案是返回null而不是string.Empty - erodewald
这可以通过在Convert函数中返回值来更简单地实现。实际上,这将简单地将未更改的值传递,但不会显示绑定错误。 - buckley
我按照你所做的方式去做了,但是出现了错误: <Window.Resources> <local:NullImageConverter x:Key="nullImageConverter"/>类型“local:NullImageConverter”未找到。请确认您没有丢失程序集引用,并且所有引用的程序集都已构建完成。 - omini data
显示剩余2条评论

19

我使用了 Pat 的 ValueConverter 技术,它非常有效。我还尝试了 TargetNullValue 技术,来自这里的 flobodob,它也非常好用。这种方法更简单、更清晰。

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

TargetNullValue更简单,不需要转换器。


6

将图像直接绑定到对象上,必要时返回"UnsetValue"

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

您的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");
        }
    }

1
虽然那可能有效,但我认为Pat的答案更好,因为你只需要定义一次转换器 - 使用你的解决方案,你必须为每个图像属性重新实现这个。 - Kai G
你正在绑定到一个字符串,但是你的属性返回对象? - pixel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接