C# 显示默认图像,并在实际图像完成加载后对其进行更改
我有一个WPF标记扩展,负责按名称检索图像,返回C# 显示默认图像,并在实际图像完成加载后对其进行更改,c#,.net,wpf,bitmapimage,markup-extensions,C#,.net,Wpf,Bitmapimage,Markup Extensions,我有一个WPF标记扩展,负责按名称检索图像,返回BitmapImage对象 <Image Source="{my:ImageProvider ImageName=myImageName}"></Image> 有没有一种方法可以更新UI以使用修改后的位图图像(类似于INotifyPropertyChanged)或者有没有其他方法来实现这一点?PriorityBinding我想您可能正在寻找。 您可以将实际图像源作为最高绑定绑定绑定到两个不同的DP,并且不要忘记将该绑定的I
BitmapImage
对象
<Image Source="{my:ImageProvider ImageName=myImageName}"></Image>
有没有一种方法可以更新UI以使用修改后的
位图图像(类似于INotifyPropertyChanged)或者有没有其他方法来实现这一点?PriorityBinding
我想您可能正在寻找。
您可以将实际图像源作为最高绑定绑定绑定到两个不同的DP,并且不要忘记将该绑定的IsAsync
属性设置为true。
一旦图像源准备就绪,它将自动替换第二个绑定
请参阅此链接以开始-我最后给出了两种方法。这两种方法都使用一个类来包装图像并实现INotifyPropertyChanged
:
class ImageSourceWrapper : ObservableObject
{
private ImageSource _image;
public ImageSource Image
{
get { return _image; }
set
{
if (value != _image)
{
_image = value;
RaiseOnPropertyChanged("Image");
}
}
}
public ImageSourceWrapper(ImageSource image)
{
Image = image;
}
}
第一种方法
一旦有了它,我就可以让我的标记扩展返回一个ImageSourceWrapper
对象并绑定到它,如下所示
<Image Source="{Binding Source={my:ImageProvider ImageName=myImageName}, Path=Image}" />
然后我可以像这样在XAML中使用它
<Image Source="{my:ImageProvider ImageName=myImageName}" />
这样,将首先显示默认图像,一旦检索到请求的图像,将显示该图像
抱歉,如果这里的代码不完全正确,我现在不在代码附近。希望目前这足以表达主要观点
private ImageSourceWrapper _imageSourceWrapper;
public override object ProvideValue(IServiceProvider serviceProvider)
{
// Get the object and the property to be bound.
IProvideValueTarget service = IProvideValueTarget)provider.GetService(typeof(IProvideValueTarget));
DependencyObject targetObject = service.TargetObject as DependencyObject;
DependencyProperty targetProperty = service.TargetProperty as DependencyProperty;
// Set up the binding with the default image.
_imageSourceWrapper = new ImageSourceWrapper(DefaultImage);
Binding binding = new Binding("Image");
binding.Source = _imageSourceWrapper;
BindingOperations.SetBinding(targetObject, targetProperty, binding);
// Retrieve the actual image asynchronously.
GetImageAsync();
return binding.ProvideValue(serviceProvider);
}
private void GetImageAsync()
{
// Get the image asynchronously.
// Freeze the image so it could be accessed from all threads regardless
// of which thread it was created on.
newImage.Freeze();
// Got the image - update the _imageSourceWrapper object.
_imageSourceWrapper = newImage;
}
<Image Source="{my:ImageProvider ImageName=myImageName}" />