【问题标题】:ImageSourceConverter error for Source=nullSource=null 的 ImageSourceConverter 错误
【发布时间】:2011-07-20 22:52:53
【问题描述】:

我将 Image 的 Source 属性绑定到一个字符串。此字符串可能为空,在这种情况下我不想显示图像。但是,我在调试输出中得到以下信息:

System.Windows.Data 错误:23:不能 将 '' 从类型 '' 转换为 类型 'System.Windows.Media.ImageSource' 为 'en-AU' 文化默认 转换;考虑使用转换器 绑定的属性。 NotSupportedException:'System.NotSupportedException: ImageSourceConverter 无法转换 从(空)。在 System.ComponentModel.TypeConverter.GetConvertFromException(对象 值)在 System.Windows.Media.ImageSourceConverter.ConvertFrom(ITypeDescriptorContext 上下文,CultureInfo 文化,对象 值)在 MS.Internal.Data.DefaultValueConverter.ConvertHelper(对象 o,类型destinationType, DependencyObject 目标元素, CultureInfo 文化,布尔值 isForward)'

如果这只是噪音,我宁愿不显示 - 有什么方法可以抑制它?

【问题讨论】:

  • 我不太确定这只是噪音。在我的应用中,我认为它会导致一些性能问题(加载所有空图像时)。
  • 是的,这肯定会导致性能问题。详情见我的回答。

标签: .net wpf image exception-handling ivalueconverter


【解决方案1】:

@AresAvatar 建议您使用 ValueConverter 是正确的,但该实现对这种情况没有帮助。这样做:

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}}"/>

【讨论】:

  • 当我考虑图像源的空值时,我的代码现在运行的速度令人惊讶。谢谢你,虽然我建议也处理 string.IsNullOrWhitespace 的情况,如果 'value' 是一个字符串。
  • 有没有办法在绑定中将 DependencyProperty.UnsetValue 指定为 TargetNullValue?它可能会消除对转换器的需要?
  • 我对此进行了非常成功的测试:TargetNullValue={x:Static DependencyProperty.UnsetValue} 注意: 如果它是一个空字符串,它将不起作用。如果您正在执行诸如在 getter 中构建字符串路径之类的操作,一种可能的解决方案是简单地返回 null 而不是 string.Empty
  • 这可以通过在 Convert 函数中返回值来变得更简单。实际上,这将简单地通过未更改的值进行管道传输,但不会显示绑定错误
  • 我按照你的做法做了,但我收到错误&lt;Window.Resources&gt; &lt;local:NullImageConverter x:Key="nullImageConverter"/&gt; 找不到类型“local:NullImageConverter”。确认您没有丢失程序集引用并且所有引用的程序集都已构建。
【解决方案2】:

我使用了 Pat 的 ValueConverter 技术,效果很好。 我还尝试了来自 here 的 flobodob 的 TargetNullValue 技术,它也很有效。它更简单、更清洁。

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

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

【讨论】:

    【解决方案3】:

    将您的图像直接绑定到对象上,并在必要时返回“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");
            }
        }
    

    【讨论】:

    • 虽然这可能有效,但我认为 Pat 的答案更好,因为您只需定义一次转换器 - 使用您的解决方案,您必须为每个 Image 属性重新实现它。
    • 您正在绑定到一个字符串,但您的属性返回对象?
    猜你喜欢
    • 2013-11-07
    • 1970-01-01
    • 2017-08-22
    • 2017-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多