为WPF图像类提供初始图像占位符



当我运行项目时发生运行时错误:错误:必须设置属性"UriSource"或属性"StreamSource"。因为这个。ImageUri是空的,我不知道为什么。ImageUri为空!帮我

我一直在使用WPF列表框使用图像作为我的列表框项。源映像路径指向托管这些映像的服务器。在高速网络上,图像显示没有任何明显的延迟。然而,在一个缓慢的链接上,用户体验明显下降,我真的想在下载和解码图像时显示一个占位符图像。

令人惊讶的是,我没有在博客圈找到解决这个问题的方法,所以我编写了一个派生类来解决这个问题。

下面的示例XAML来自我的项目容器样式。我将Image替换为我的本地类实现local:ImageLoader.

<Window.Resources>
<DataTemplate DataType="{x:Type local:MyData}">
...
<StackPanel Grid.Column="0" Margin="5">
<Border BorderThickness="0">
<MyControl:ImageLoader Width="50" Height="50" ImageUri="{Binding Path=profile_image_url_https, FallbackValue=profile_image_url_https}" InitialImage="/MyProject;component/Images/nopic.png"  HorizontalAlignment="Left"></imgz:ImageLoader>
</Border>
</StackPanel>
...
</DataTemplate>
</Window.Resources>
<Grid>
<ListBox ItemsSource="{Binding Source = {StaticResource MyData}}"    />
</Grid>

初始图像处理的核心是在OnLoaded()方法中,我使用BitmapImage作为源,并将UriSource设置为派生类的ImageUri依赖属性,这允许数据绑定。当下载完成或接收到失败事件时,将初始映像更新为实际映像。这个类还允许你指定一个LoadFailedImage。

public class ImageLoader : Image
{
    public static readonly DependencyProperty ImageUriProperty = DependencyProperty.Register(
        "ImageUri", typeof(Uri), typeof(ImageLoader), new PropertyMetadata(null, null));
    private BitmapImage loadedImage;
    public ImageLoader()
    {
        this.Loaded += this.OnLoaded;
    }
    public string LoadFailedImage
    {
        get;
        set;
    }
    public Uri ImageUri
    {
        get {return this.GetValue(ImageUriProperty) as Uri;}
        set {this.SetValue(ImageUriProperty, value);}
    }
    public string InitialImage
    {
        get;
        set;
    }
    private new ImageSource Source
    {
        get {return base.Source;}
        set {base.Source = value;}
    }
    private void OnLoaded(object sender, RoutedEventArgs e)
    {
        // Loading the specified image            
        this.loadedImage = new BitmapImage();
        this.loadedImage.BeginInit();
        this.loadedImage.CacheOption = BitmapCacheOption.OnDemand;
        this.loadedImage.DownloadCompleted += this.OnDownloadCompleted;
        this.loadedImage.DownloadFailed += this.OnDownloadFailed;
        this.loadedImage.UriSource = this.ImageUri;
        this.loadedImage.EndInit();
        // The image may be cached, in which case we will not use the initial image
        if (!this.loadedImage.IsDownloading)
        {
            this.Source = this.loadedImage;
        }
        else
        {
            // Create InitialImage source if path is specified
            if (!string.IsNullOrWhiteSpace(this.InitialImage))
            {
                BitmapImage initialImage = new BitmapImage();
                // Load the initial bitmap from the local resource
                initialImage.BeginInit();
                initialImage.UriSource = new Uri(this.InitialImage, UriKind.Relative);
                initialImage.DecodePixelWidth = (int)this.Width;
                initialImage.EndInit();
                // Set the initial image as the image source
                this.Source = initialImage;                
            }
        }
        e.Handled = true;
    }
    private void OnDownloadFailed(object sender, ExceptionEventArgs e)
    {
        if (!string.IsNullOrWhiteSpace(this.LoadFailedImage))
        {
            BitmapImage failedImage = new BitmapImage();
            // Load the initial bitmap from the local resource
            failedImage.BeginInit();
            failedImage.UriSource = new Uri(this.LoadFailedImage, UriKind.Relative);
            failedImage.DecodePixelWidth = (int)this.Width;
            failedImage.EndInit();
            this.Source = failedImage;
        }
    }
    private void OnDownloadCompleted(object sender, EventArgs e)
    {
        this.Source = this.loadedImage;
    }
}

当我运行项目时,发生了一个运行时错误:错误:必须设置属性"UriSource"或属性"StreamSource"。因为这个。ImageUri是空的,我不知道为什么。ImageUri为空!帮我

如果不是InitialImage="/MyProject;component/Images/nopic.png"中的分号错误,
也许最好在ImageUri

中将InitialImage设置为Default
 public static readonly DependencyProperty ImageUriProperty = DependencyProperty.Register(
    "ImageUri", typeof(Uri), typeof(ImageLoader), new PropertyMetadata(new Uri("/MyProject/component/Images/nopic.png"), null));


更新:

您必须绑定到Image.Source,您可以使用PriorityBinding来显示占位符。

<Image.Source>
    <PriorityBinding>
        <!--highest priority sources are first in the list-->
        <Binding Path="YourImageUri"
           IsAsync="True" />
        <Binding Path="InitialImageUri"
           IsAsync="True" />
    </PriorityBinding>
</Image.Source>

对于"LoadFailedImage",a将订阅Image.ImageFailed事件。

相关内容

  • 没有找到相关文章

最新更新