HypernovaDesktop Components · docs
Binarymission
WPF › Pan And Zoom Provider › ZoomPanControl

ZoomPanControl

class.NET 6 / 8 / 10.NET Framework 4.8Binarymission.WPF.Controls.ContentControls

A content control that lets the user zoom into whatever it holds with the mouse wheel or the keyboard, and drag it around to pan, as in a map or photo viewer.

public class ZoomPanControl : ContentControl

Inherits from / implements: ContentControl

Remarks

Put anything larger or more detailed than the space it has inside it – a floor plan, a schematic, a scanned document, a chart, a Canvas of shapes – and the user can look at the whole of it and then zoom into the detail. It opens showing the whole of its content, scaled to fit (IsInitialViewFitted).

What the user can do

InputEffect

Mouse wheel

Zooms in or out by ZoomStep, keeping the point under the pointer where it is.

Drag with the left button

Pans, while IsPanningEnabled is on. The content cannot be dragged out of sight, and content smaller than the control stays centred.

ZoomInKeyboardKey / ZoomOutKeyboardKey

Zooms in or out about the centre (Up and Down arrows by default).

AutomaticZoomOutKey

Returns to the opening view (Escape by default), while IsAutomaticZoomingoutByKeypressEnabled is on.

Zooming is animated over about a fifth of a second; panning follows the pointer exactly. The keys work while the control has keyboard focus, which it takes when the user starts a pan.

From code

ZoomLevel reads and sets the scale, ZoomToFit shows the whole content, ResetView returns to the opening view, and FitZoomLevel is the scale at which everything fits – the pieces of a zoom slider or a "Fit" button. ZoomMinimumDepth and ZoomMaximumDepth bound every zoom.

Layout

The control clips its content to its own bounds, and places the content at its top-left corner (Control.HorizontalContentAlignment and Control.VerticalContentAlignment default to Left and Top), because it positions the content itself. Give the content a size of its own – an image's natural size, or a Canvas with FrameworkElement.Width and FrameworkElement.Height – since that is what is scaled and fitted. A view that fits the content stays fitted when the control is resized; any other view keeps its scale. Replacing the content returns to the opening view.

Examples

A zoomable floor plan with a toolbar of zoom buttons.

<Window x:Class="Facilities.PlanWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:zp="clr-namespace:Binarymission.WPF.Controls.ContentControls;assembly=Binarymission.WPF.Controls.ZoomPanControl"
        Title="Second floor" Width="1000" Height="700">

    <DockPanel>
        <ToolBar DockPanel.Dock="Top">
            <Button Content="Zoom in"  Click="OnZoomIn" />
            <Button Content="Zoom out" Click="OnZoomOut" />
            <Button Content="Fit"      Click="OnFit" />
        </ToolBar>

        <zp:ZoomPanControl x:Name="Plan" Background="White"
                           ZoomStep="1.25" ZoomMinimumDepth="0.1" ZoomMaximumDepth="8">
            <Image Source="Plans/second-floor.png" Stretch="None" />
        </zp:ZoomPanControl>
    </DockPanel>
</Window>

The handlers.

private void OnZoomIn(object sender, RoutedEventArgs e)  { Plan.ZoomLevel *= 1.25; }
private void OnZoomOut(object sender, RoutedEventArgs e) { Plan.ZoomLevel /= 1.25; }
private void OnFit(object sender, RoutedEventArgs e)     { Plan.ZoomToFit(); }

See also

Members at a glance

Constructors
ZoomPanControlCreates a zoom and pan control that can take keyboard focus, ready for its content.
Properties
AutomaticZoomOutKeyGets or sets the key that returns the view to how the control opened.
FitZoomLevelGets the scale at which the whole of the content fits inside the control.
IsAutomaticZoomingoutByKeypressEnabledGets or sets whether pressing AutomaticZoomOutKey returns the view to how the control opened.
IsInitialViewFittedGets or sets whether the control opens showing the whole of its content scaled to fit, rather than at the content's own size.
IsPanningEnabledGets or sets whether the user can drag the content with the left mouse button to pan it.
ZoomInKeyboardKeyGets or sets the key that zooms in, about the centre of the control.
ZoomLevelGets or sets the scale the content is shown at, where 1 is its own size.
ZoomMaximumDepthGets or sets the largest scale the user can zoom in to.
ZoomMinimumDepthGets or sets the smallest scale the user can zoom out to.
ZoomOutKeyboardKeyGets or sets the key that zooms out, about the centre of the control.
ZoomStepGets or sets how much one notch of the mouse wheel, or one press of a zoom key, magnifies or shrinks the content.
Methods
OnApplyTemplateAttaches the zoom and pan transform to the content once the template has been applied, and asks for the opening view.
OnContentChangedAttaches the zoom and pan transform to new content, and returns to the opening view for it.
ResetViewReturns to the view the control opened with: the whole content scaled to fit, or the content at its own size if IsInitialViewFitted is off.
ZoomToFitZooms so that the whole of the content is visible, centred in the control.
Fields
AutomaticZoomOutKeyPropertyIdentifies the AutomaticZoomOutKey dependency property.
IsAutomaticZoomingoutByKeypressEnabledPropertyIdentifies the IsAutomaticZoomingoutByKeypressEnabled dependency property.
IsInitialViewFittedPropertyIdentifies the IsInitialViewFitted dependency property.
IsPanningEnabledPropertyIdentifies the IsPanningEnabled dependency property.
ZoomInKeyboardKeyPropertyIdentifies the ZoomInKeyboardKey dependency property.
ZoomMaximumDepthPropertyIdentifies the ZoomMaximumDepth dependency property.
ZoomMinimumDepthPropertyIdentifies the ZoomMinimumDepth dependency property.
ZoomOutKeyboardKeyPropertyIdentifies the ZoomOutKeyboardKey dependency property.
ZoomStepPropertyIdentifies the ZoomStep dependency property.

Constructors

ZoomPanControl

public ZoomPanControl()

Creates a zoom and pan control that can take keyboard focus, ready for its content.

Properties

AutomaticZoomOutKey

public Key AutomaticZoomOutKey

Gets or sets the key that returns the view to how the control opened.

Value
The default is Escape.
Remarks

Used only while IsAutomaticZoomingoutByKeypressEnabled is on. It takes precedence over ZoomInKeyboardKey and ZoomOutKeyboardKey if set to the same key.

Example
<zp:ZoomPanControl AutomaticZoomOutKey="Home" />

FitZoomLevel

public double FitZoomLevel

Gets the scale at which the whole of the content fits inside the control.

Value
The scale that fits the content's width and height both within the control, held within ZoomMinimumDepth and ZoomMaximumDepth; or 1 while the size of the control or of its content is not yet known.
Remarks

Use it to label a "Fit" button or to mark the fitted position on a zoom slider; ZoomToFit applies it.

See also

IsAutomaticZoomingoutByKeypressEnabled

public bool IsAutomaticZoomingoutByKeypressEnabled

Gets or sets whether pressing AutomaticZoomOutKey returns the view to how the control opened.

Value
true to enable the key. The default is true.
Remarks

The key does what ResetView does: it shows the whole content scaled to fit, or the content at its own size when IsInitialViewFitted is off. It works while the control has keyboard focus.

See also

IsInitialViewFitted

public bool IsInitialViewFitted

Gets or sets whether the control opens showing the whole of its content scaled to fit, rather than at the content's own size.

Value
true to open on the fitted view. The default is true.
Remarks

The opening view is applied once the control and its content have been laid out, and again whenever the content is replaced. Opening on the whole content shows the user its structure and makes zooming in the obvious next move; opening at its own size (false) suits content meant to be read at 1:1, starting from its top-left corner.

It also decides what ResetView and AutomaticZoomOutKey return to.

IsPanningEnabled

public bool IsPanningEnabled

Gets or sets whether the user can drag the content with the left mouse button to pan it.

Value
true to allow panning. The default is true.
Remarks

Turn it off when the content itself needs left-button drags – shapes the user moves, a selection rectangle. Zooming still works. While panning is off the control does not take keyboard focus when clicked, so the zoom keys work only once something else has given it focus. Turning it off in the middle of a drag ends the drag.

ZoomInKeyboardKey

public Key ZoomInKeyboardKey

Gets or sets the key that zooms in, about the centre of the control.

Value
The default is Up, the Up arrow.
Remarks

Each press zooms by ZoomStep. It works while the control has keyboard focus.

Example
<zp:ZoomPanControl ZoomInKeyboardKey="Add" ZoomOutKeyboardKey="Subtract" />
See also

ZoomLevel

public double ZoomLevel

Gets or sets the scale the content is shown at, where 1 is its own size.

Value
The current scale. It starts at FitZoomLevel when IsInitialViewFitted is on, and at 1 otherwise.
Remarks

Setting it zooms about the centre of the control, animated, and is held within ZoomMinimumDepth and ZoomMaximumDepth. Reading it straight afterwards gives the new scale, even while the animation is still running. It changes too as the user zooms with the wheel or the keys.

It is a plain property, not a dependency property, so it cannot be the target of a binding; set it from an event handler, such as a slider's ValueChanged.

Example
// A zoom slider from 10% to 800%, and a label showing the zoom as a percentage.
zoomSlider.Minimum = 0.1;
zoomSlider.Maximum = 8;
zoomSlider.ValueChanged += (sender, e) =>
{
    plan.ZoomLevel = e.NewValue;
    zoomLabel.Text = plan.ZoomLevel.ToString("P0");
};
See also

ZoomMaximumDepth

public double ZoomMaximumDepth

Gets or sets the largest scale the user can zoom in to.

Value
A scale, where 1 shows the content at its own size and 4 at four times its size. The default is MaxValue: no limit.
Remarks

Every zoom – the wheel, the keys, ZoomLevel and the fitted view – is held to it. A value below ZoomMinimumDepth, or not a number, is read as no limit.

See also

ZoomMinimumDepth

public double ZoomMinimumDepth

Gets or sets the smallest scale the user can zoom out to.

Value
A scale, where 1 shows the content at its own size and 0.5 at half its size. The default is MinValue, which is read as 0.01: one hundredth of the content's size.
Remarks

Every zoom, including the fitted view, is held to it, so a minimum above FitZoomLevel stops the user zooming out far enough to see the whole content. A value below 0.01, or not a number, is read as 0.01.

See also

ZoomOutKeyboardKey

public Key ZoomOutKeyboardKey

Gets or sets the key that zooms out, about the centre of the control.

Value
The default is Down, the Down arrow.
Remarks

Each press zooms out by ZoomStep. It works while the control has keyboard focus.

See also

ZoomStep

public double ZoomStep

Gets or sets how much one notch of the mouse wheel, or one press of a zoom key, magnifies or shrinks the content.

Value
The default is 1.4: each notch magnifies by 40%, and each notch the other way divides by 1.4.
Remarks

The value is read two ways. Greater than 1, it is a multiplier: 1.25 magnifies by 25% per notch. Between 0 and 1 inclusive, it is the fraction to add: 0.25 also magnifies by 25% per notch, and 1 doubles. Zero, a negative value or a value that is not a finite number is read as 1.4.

Smaller steps give finer control on a high-resolution wheel or touchpad; larger ones get from the whole view to the detail in fewer notches.

See also

Methods

OnApplyTemplate

public override void OnApplyTemplate()

Attaches the zoom and pan transform to the content once the template has been applied, and asks for the opening view.

OnContentChanged

protected override void OnContentChanged(object oldContent, object newContent)

Attaches the zoom and pan transform to new content, and returns to the opening view for it.

Parameters
oldContent
The content being replaced.
newContent
The new content. When it is a FrameworkElement, it is what is zoomed; otherwise the element that presents it is.
Remarks

The new content does not inherit the scale or position the old content was left at. Call the base method when overriding.

ResetView

public void ResetView()

Returns to the view the control opened with: the whole content scaled to fit, or the content at its own size if IsInitialViewFitted is off.

Remarks

The change is animated. AutomaticZoomOutKey does the same from the keyboard.

See also

ZoomToFit

public void ZoomToFit()

Zooms so that the whole of the content is visible, centred in the control.

Remarks

The zoom is animated. The view then stays fitted as the control is resized, until the user zooms or pans. Before the control and its content have been laid out it shows the content at its own size instead.

See also

Fields

AutomaticZoomOutKeyProperty static

public static readonly DependencyProperty AutomaticZoomOutKeyProperty

Identifies the AutomaticZoomOutKey dependency property.

IsAutomaticZoomingoutByKeypressEnabledProperty static

public static readonly DependencyProperty IsAutomaticZoomingoutByKeypressEnabledProperty

Identifies the IsAutomaticZoomingoutByKeypressEnabled dependency property.

IsInitialViewFittedProperty static

public static readonly DependencyProperty IsInitialViewFittedProperty

Identifies the IsInitialViewFitted dependency property.

IsPanningEnabledProperty static

public static readonly DependencyProperty IsPanningEnabledProperty

Identifies the IsPanningEnabled dependency property.

ZoomInKeyboardKeyProperty static

public static readonly DependencyProperty ZoomInKeyboardKeyProperty

Identifies the ZoomInKeyboardKey dependency property.

ZoomMaximumDepthProperty static

public static readonly DependencyProperty ZoomMaximumDepthProperty

Identifies the ZoomMaximumDepth dependency property.

ZoomMinimumDepthProperty static

public static readonly DependencyProperty ZoomMinimumDepthProperty

Identifies the ZoomMinimumDepth dependency property.

ZoomOutKeyboardKeyProperty static

public static readonly DependencyProperty ZoomOutKeyboardKeyProperty

Identifies the ZoomOutKeyboardKey dependency property.

ZoomStepProperty static

public static readonly DependencyProperty ZoomStepProperty

Identifies the ZoomStep dependency property.