Click here to Skip to main content
15,435,839 members
Articles / Programming Languages / C#
Posted 15 Mar 2011

Tagged as


20 bookmarked

A Silverlight custom control for zooming and panning with a small window to see he image with thumb

Rate me:
Please Sign up or sign in to vote.
4.75/5 (5 votes)
15 Mar 2011CPOL3 min read
Zooming and panning an image in a Silverlight application.


This article provides the ability to interactively view high resolution images. You can zoom in and zoom out images. This Silverlight custom control enables deep zooming using Storyboard animation and smooth panning by handling the MouseLeftButtonDown, MouseLeftButtonUp, and MouseMove events. The following features are included:

  • Deep zooming
  • Panning an image
  • Small window with thumb to view the exact location of the zoomed image


Deep zooming is a pretty straightforward functionality and is done with the ScaleTransform property. Panning is done by setting the offset X and Y of the content. Silverlight 3 has a MultiscaleImage control for zooming multi-resolution images. It has a Source property to set multiple images.

In this article, I have created a custom zoom control for zooming and panning single images with animation for smooth panning.

Using the Code

  1. Creating a custom zoom and pan control using Silverlight 4 Class Library
  2. First, create a class for zoom and pan which inherits from ContentControl and implements the IScrollInfo interface to move the thumb image within the area. This class contains Rectangle properties and animation methods for setting the content offset in X,Y coordinates with point zooming. It overrides the Size method to change the image size and scale of images. It has a Generic Style for setting the Template for the control with properties. This style is imported to the class.

  3. Using the control in a Silverlight application
    • Create a Silverlight application to use the zoom and pan custom Silverlight control.
    • In the Silverlight application, create an enum to handle the mouse modes.

      public enum MouseHandlingMode

      Create a class having Dependency Properties for setting the scale, width, height, offset etc., and implement the InotifyPropertyChanged interface to change the property value.

    • Declare all the Dependecy properties and the collection for the example.
    • C#
      public class DataModel : INotifyPropertyChanged
          private ObservableCollection<RectangleData> rectangles = 
                  new ObservableCollection<RectangleData>();
          private double contentScale = 1;
          public static DataModel Instance
              get{return instance; }
          public ObservableCollection<RectangleData> Rectangles
              get{return rectangles; }
          public double ContentScale
              get{return contentScale; }
                  contentScale = value;
          . . . . .

      Create a Converter class to convert the scale value to percent for the Slider control:

      public class ScaleToPercentConverter : IValueConverter
          public object Convert(object value, Type targetType, object parameter, 
                                CultureInfo culture)
              return (double)(int)((double)value * 100.0);
          public object ConvertBack(object value, Type targetType, object parameter, 
                                    CultureInfo culture)
              return (double)value / 100.0;

      Create a class for drawing the rectangle.

    • Now create the UserControl (HAEZoomingControl.xaml) to use the custom Silverlight control in the page.
      • Add the custom ZoomingAndPanning control to the page.
      • XML
        <ZoomAndPan:ZoomAndPanControl Grid.Row="0"
            ContentScale= "{Binding Source={StaticResource 
                         TypeProvider}, Path=Instance.ContentScale, Mode=TwoWay}"
            ContentOffsetX= "{Binding Source={StaticResource 
                         TypeProvider}, Path=Instance.ContentOffsetX, Mode=TwoWay}"
            ContentOffsetY= "{Binding Source={StaticResource TypeProvider}, 
                         Path=Instance.ContentOffsetY, Mode=TwoWay}"
            ContentViewportWidth="{Binding Source={StaticResource TypeProvider}, 
                         Path=Instance.ContentViewportWidth, Mode=TwoWay}"
            ContentViewportHeight= "{Binding Source={StaticResource TypeProvider}, 
                         Path=Instance.ContentViewportHeight, Mode=TwoWay}"
            Background="{StaticResource pageBackground}"
      • Add ZoomIn, ZoomOut buttons and a Silder:
      • XML
        <Button x:Name="btnZoomOut"
               <Slider Grid.Column="10"
                  Minimum="{Binding MinPercentage}"
                  Maximum="{Binding MaxPercentage}"
                  Value= "{Binding ElementName=zoomAndPanControl, 
                          Path=ContentScale, Converter={StaticResource 
                          scaleToPercentConverter},Mode=TwoWay}" />
               <Button x:Name="btnZoomIn"
      • Add a popup the contains a small image in a grid and a thumb (rectangle) to view the zooming image position.
      • XML
        <Popup x:Name="MyPOP"
            <StackPanel Width="200" Height="200">
            <ZoomAndPan:ZoomAndPanControl x:Name="overview"
                Width="200" Height="200"
                Background="{StaticResource popupBackground}"
            <Grid Width="{Binding Source={StaticResource TypeProvider}, 
               Height="{Binding Source={StaticResource TypeProvider}, 
            <Image x:Name="content2" Source="{Binding ImgSource}"
                VerticalAlignment="Center" HorizontalAlignment="Center"></Image>
              <Thumb x:Name="overviewZoomRectThumb"
                Canvas.Left="{Binding Source={StaticResource TypeProvider}, 
                             Path=Instance.ContentOffsetX, Mode=TwoWay}"
                Canvas.Top="{Binding Source={StaticResource TypeProvider}, 
                            Path=Instance.ContentOffsetY, Mode=TwoWay}"
                Width="{Binding Source={StaticResource TypeProvider}, 
                       Path=Instance.ContentViewportWidth, Mode=TwoWay}"
                Height="{Binding Source={StaticResource TypeProvider}, 
                        Path=Instance.ContentViewportHeight, Mode=TwoWay}"
        <ControlTemplate TargetType="Thumb">
          <Border BorderBrush="Black"
              BorderThickness="3" Background="Yellow"
              CornerRadius="3" />
    • In the code-behind (HAEZoomingControl.xaml.cs), write events for MouseMove, LeftButtonDown, LeftButtonUp, and DoubleClcik. The MouseDoubleClick event is not available in Silverlight so you can use MouseLeftButtonDown instead to count clicks.
    • For example:

      • Declare a timer variable to detect double click:
      • C#
        DispatcherTimer _timer;
      • Declare an interval variable:
      • C#
        private static int INTERVAL = 200;
      • In the default constructor, create an instance of the timer.
      • C#
        public HAEZoomingControl()
            _timer = new DispatcherTimer();
            zoomAndPanControl.ContentOffsetY = 200;
            _timer.Interval = new TimeSpan(0, 0, 0, 0, INTERVAL);
            _timer.Tick += new EventHandler(_timer_Tick);
      • Add an event to stop the timer:
      • C#
        void _timer_Tick(object sender, EventArgs e)
      • In the MouseLeftButtonDown event of the control use, times to check for double click.
      • C#
        private void zoomAndPanControl_MouseLeftButtonDown(
                object sender, MouseButtonEventArgs e)
            if (zoomAndPanControl.ContentScale <= (MaxPercentage / 100))
                btnZoomIn.IsEnabled = true;
            if (zoomAndPanControl.ContentScale >= (MinPercentage / 100))
                btnZoomOut.IsEnabled = true;
            if (_timer.IsEnabled)
                if (zoomAndPanControl.ContentScale <= (MaxPercentage / 100))
                    sb = new Storyboard();
                    DoubleAnimation db = new DoubleAnimation();
                    sb.Completed += new EventHandler(sb_Completed);
                    db.To = zoomAndPanControl.ContentScale + 0.2;
                    db.Duration = new Duration(TimeSpan.FromSeconds(0.3));
                    Storyboard.SetTarget(db, zoomAndPanControl);
                               new PropertyPath("ContentScale"));
                    btnZoomIn.IsEnabled = false;
                if (zoomAndPanControl.ContentScale >= (MinPercentage / 100))
                    origZoomAndPanControlMouseDownPoint = 
                    origContentMouseDownPoint = e.GetPosition(content);
                    mouseHandlingMode = MouseHandlingMode.Panning;
                    if (mouseHandlingMode != MouseHandlingMode.None)
                        e.Handled = true;
      • Write code for the other events and run the application.

In the image below, you can see a zoomed image and a small image on the bottom-right side of the canvas to see the offset position of the zoomed image using the yellow thumb marker.

You can zoom the image using these controls in the bottom-right corner of the page: ZoomIn, ZoomOut buttons and the Slider control.

Points of Interest

Before creating this application in Silverlight, I referred to this article byf Ashley Davis: A WPF custom control for zooming and panning). His article was great for understanding how to create rectangles, use a Dependency Property, create a custom control with Themes using the DefaultStyleKey property, and scale images etc. Here is the link to the control:


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Written By
Team Leader Reputed IT Company
India India
Having 9+ years of experience in Microsoft.Net Technology.
Experience in developing applications on Microsoft .NET Platform ( Asp.Net, WPF, Silverlight, Windows Phone 7/8).
Experience and knowledge of software design methodologies (Agile), object oriented design, and software design patterns (MVVM).
Experience in Developing android mobile application using Xamarin (mono for android) framework.

Comments and Discussions

QuestionGreat Solution Pin
Winner7814-May-14 2:03
MemberWinner7814-May-14 2:03 
QuestionHow to zoom in zoom out using zoomandpancontrol for multiple images Pin
bSatyadeep22-Jul-12 20:29
MemberbSatyadeep22-Jul-12 20:29 
QuestionGood work, but... Pin
djeezes19-Jul-12 23:40
Memberdjeezes19-Jul-12 23:40 
QuestionCombined Silverlight sourcecode base with WPF version Pin
George I. Birbilis18-Jun-12 7:42
MemberGeorge I. Birbilis18-Jun-12 7:42 
Question Pin
iimagegrapher23-Nov-11 19:08
Memberiimagegrapher23-Nov-11 19:08 
AnswerRe: Pin
Hiren Khirsaria12-Dec-11 0:00
professionalHiren Khirsaria12-Dec-11 0:00 
GeneralMin and Max value for contentOffsetX and contentOffsetY [modified] Pin
kapil bhavsar18-May-11 20:30
Memberkapil bhavsar18-May-11 20:30 
GeneralRe: Min and Max value for contentOffsetX and contentOffsetY Pin
robbiegis31-May-11 22:42
Memberrobbiegis31-May-11 22:42 
GeneralMy vote of 5 Pin
mbcrump24-Mar-11 7:47
mentormbcrump24-Mar-11 7:47 
GeneralMy vote of 5 Pin
Member 265878723-Mar-11 20:41
MemberMember 265878723-Mar-11 20:41 
GeneralWhoa..... Pin
Ashley Davis15-Mar-11 5:29
MemberAshley Davis15-Mar-11 5:29 
GeneralRe: Whoa..... Pin
Indivara19-Mar-11 23:43
professionalIndivara19-Mar-11 23:43 
GeneralRe: Whoa..... Pin
George I. Birbilis30-Apr-12 8:51
MemberGeorge I. Birbilis30-Apr-12 8:51 
GeneralRe: Whoa..... Pin
George I. Birbilis18-Jun-12 7:45
MemberGeorge I. Birbilis18-Jun-12 7:45 
GeneralNeeds work Pin
Dave Kreskowiak14-Mar-11 11:07
mveDave Kreskowiak14-Mar-11 11:07 
GeneralIs There a Reason... Pin
#realJSOP14-Mar-11 8:44
mva#realJSOP14-Mar-11 8:44 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.