Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 显示默认图像,并在实际图像完成加载后对其进行更改_C#_.net_Wpf_Bitmapimage_Markup Extensions - Fatal编程技术网

C# 显示默认图像,并在实际图像完成加载后对其进行更改

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

我有一个WPF标记扩展,负责按名称检索图像,返回
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}" />