Silverlight Tip of the Day #13 - How to Get an Images Dimensions in Silverlight.

Since Silverlight is based upon an asynchronized model, getting an image width and height immediately after loading it is not possible. However, you can monitor its download progress and obtain the image dimensions once the progress has reached 100%.

Below is a sample that demonstrates how to do this. Few important notes:

  • BitmapImage requires the namespace System.Windows.Media.Imaging;
  • ActualWidth and ActualHeight are calculated values. The calculation happens after a layout pass. Therefore, the image must be in the tree in order for hits size to be accounted for. Thus my call to GameCanvas.Children.Add(grass);
  • The image you are adding to your canvas must be first added to your Silverlight application project in Visual Studio. Make certain your path to this image is correct.
  • The call to Dispatcher.BeginInvoke(delegate() { … } ); is required before you obtain the Width/Height or they might be intermittently zero.
 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Net;
 using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Documents;
 using System.Windows.Input;
 using System.Windows.Media;
 using System.Windows.Media.Animation;
 using System.Windows.Shapes;
 using System.Windows.Media.Imaging;
  
 namespace SilverlightApplication12
 {
     
     public partial class Page : UserControl
     {
         private Image grass;
  
         public Page()
         {
             InitializeComponent();
             LoadImage("grass.png");
         }
  
         private void LoadImage(string path)
         {
             Uri uri = new Uri(path, UriKind.Relative);
             BitmapImage bitmapImage = new BitmapImage();
             bitmapImage.UriSource = uri;
             bitmapImage.DownloadProgress += 
                 new EventHandler<DownloadProgressEventArgs>(bitmapImage_DownloadProgress);
             
             grass = new Image();
             grass.Source = bitmapImage;
             GameCanvas.Children.Add(grass);
         }
  
         void bitmapImage_DownloadProgress(object sender, DownloadProgressEventArgs e)
         {
             if (e.Progress == 100)
             {
                 Dispatcher.BeginInvoke(delegate()
                 {
                    double height = grass.ActualHeight;
                    double width = grass.ActualWidth;
                 });
             }
         }
     }
 }

Page.xaml:

 <UserControl x:Class="SilverlightApplication12.Page"
     xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" 
     Width="400" Height="300">
     <Grid x:Name="LayoutRoot" Background="White">
         <ContentControl x:Name="MyContent">
             <Canvas x:Name="GameCanvas" ></Canvas>
         </ContentControl>                              
     </Grid>
 </UserControl>

Thank you,

--Mike Snow

 Subscribe in a reader

Comments