Note that there are some explanatory texts on larger screens.

plurals
  1. POProviding an initial image placeholder for the WPF Image class
    text
    copied!<p><strong>When i run the project a runtime error ocure: Error: Property 'UriSource' or property 'StreamSource' must be set. because this.ImageUri is null , i don't know why this.ImageUri be null ! help me</strong></p> <p>I have been working with the WPF ListBox using images as my list box items. The sourced image path points to a server hosting those images. While on fast network, the images appeared without any noticeable delay. However it became apparent over a slow link that the user experience degraded and I really wanted to show a placeholder image while the image was downloaded and decoded.</p> <p>Surprisingly, I didn't find a solution in the blogosphere for this issue so I coded up a derived class to address this.</p> <p>The sample XAML below is from my item container style. I replaced Image with my local class implementation local:ImageLoader.</p> <pre><code>&lt;Window.Resources&gt; &lt;DataTemplate DataType="{x:Type local:MyData}"&gt; ... &lt;StackPanel Grid.Column="0" Margin="5"&gt; &lt;Border BorderThickness="0"&gt; &lt;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"&gt;&lt;/imgz:ImageLoader&gt; &lt;/Border&gt; &lt;/StackPanel&gt; ... &lt;/DataTemplate&gt; &lt;/Window.Resources&gt; &lt;Grid&gt; &lt;ListBox ItemsSource="{Binding Source = {StaticResource MyData}}" /&gt; &lt;/Grid&gt; </code></pre> <p>The heart of the handling for the initial image is in the OnLoaded() method, where I use a BitmapImage as the source and set the UriSource to the derived class' ImageUri dependency property, which allows for data binding. The initial image is updated to the actual image when the download completes or when a failure event is received. The class also optionally allows you to specify a "LoadFailedImage".</p> <pre><code>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; } } </code></pre> <p><strong>When i run the project a runtime error ocured: Error: Property 'UriSource' or property 'StreamSource' must be set. because this.ImageUri is null , i don't know why this.ImageUri be null ! help me</strong></p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload