我有一个场景,我将Image Sources设置为null,稍后解析然后显示。有什么好办法阻止我的代码抛出绑定错误?
一个例子:
System.Windows.Data错误:23:无法将''从类型''转换为'en-US'文化的'System.Windows.Media.ImageSource',默认转换为;考虑使用Binding的Converter属性。 NotSupportedException:'System.NotSupportedException:ImageSourceConverter无法转换(null)。 at System.ComponentModel.TypeConverter.GetConvertFromException(Object value) 在System.Windows.Media.ImageSourceConverter.ConvertFrom(ITypeDescriptorContext context,CultureInfo culture,Object value) 在MS.Internal.Data.DefaultValueConverter.ConvertHelper(Object o,Type destinationType,DependencyObject targetElement,CultureInfo culture,Boolean isForward)'
XAML
<Image x:Name="image" Height="Auto" Width="Auto" Opacity="0">
<Image.Effect>
<DropShadowEffect/>
</Image.Effect>
<Image.Source>
<Binding Path="ImageStream">
<Binding.ValidationRules>
<validationRules:NotNullStreamValidationRule/>
</Binding.ValidationRules>
</Binding>
</Image.Source>
</Image>
C#
namespace FlickrDemo.ViewModel
{
public class FlickrPhotoViewModel : ViewModelBase
{
public const string ImageStreamPropertyName = "ImageStream";
private Stream _imageStream = null;
public Stream ImageStream
{
get
{
return _imageStream;
}
set
{
if (_imageStream == value)
{
return;
}
_imageStream = value;
RaisePropertyChanged(ImageStreamPropertyName);
}
}
public const string IsLoadingPropertyName = "IsLoading";
private bool _isLoading = false;
public bool IsLoading
{
get
{
return _isLoading;
}
set
{
if (_isLoading == value)
{
return;
}
_isLoading = value;
RaisePropertyChanged(IsLoadingPropertyName);
}
}
public const string PhotoIDPropertyName = "PhotoID";
private string _photoID = String.Empty;
public string PhotoID
{
get
{
return _photoID;
}
set
{
if (_photoID == value)
{
return;
}
var oldValue = _photoID;
_photoID = value;
RaisePropertyChanged(PhotoIDPropertyName);
}
}
public FlickrPhotoViewModel(string photoID)
{
this.PropertyChanged += async (s, e) =>
{
if (e.PropertyName == ImageStreamPropertyName)
{
if (!(ImageStream == null || ImageStream == Stream.Null))
{
IsLoading = false;
}
}
};
IsLoading = true;
PhotoID = photoID;
}
}
}
答案 0 :(得分:2)
我遇到了同样的问题,试图使用字符串URI(而不是Stream)。我通过在ImageSource类型的视图模型上设置属性来解决此问题,ImageSource是Image上的Source属性的类型,并将Source绑定到该属性。这可以从混合中获得任何自动转换。在新属性中,处理null case,然后遵循标准ImageSourceConverter。在你的情况下,我认为这看起来像这样:
代码:
public const string ImageStreamPropertyName = "ImageStream";
private Stream _imageStream = null;
public Stream ImageStream
{
get
{
return _imageStream;
}
set
{
if (_imageStream == value)
{
return;
}
_imageStream = value;
RaisePropertyChanged(ImageStreamPropertyName);
// Raise for ImageSource too since it changes with ImageStream
RaisePropertyChanged("ImageSource");
}
}
public ImageSource ImageSource
{
get
{
if (ImageStream == null)
return null;
return (ImageSource)new ImageSourceConverter().ConvertFrom(ImageStream);
}
}
XAML:
<Image.Source>
<Binding Path="ImageSource" />
</Image.Source>
答案 1 :(得分:1)
问题是ImageStream
属性的数据类型。没有转换器知道如何处理null情况:
System.Windows.Data错误:23:无法将''从类型''转换为'en-US'文化的'System.Windows.Media.ImageSource',默认转换为; 考虑使用Binding的Converter属性
解决此问题的一种可能性是实现自己的IValueConverter实施。如果输入值是流,则返回它。如果不是,则返回null。如果这不起作用,请返回一个空的假人ImageSource
。
类似的东西:
public class ImageStreamForwardConverter : IValueConverter{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture){
if(null == value){
return null;
}else if(value is Stream){
return value;
}else{
throw new InvalidOperationException("Unsupported type");
}
....
答案 2 :(得分:0)
Pat在以下链接中的回答对我来说很有用,它涉及一个简单的值转换器,在null的情况下返回DependencyProperty.UnsetValue。