Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF and Silverlight controls and layouts pan and zoom capabilities

I would like to understand the general requirements for WPF/Silverlight layout for making it possible to implement pan&zoom (drag and zoom) features. I don't mean pan&zoom for an image but for a total page (window) layout (or part of it) with some controls.

What features of the layout and what features of used custom controls make layout fixed and pan&zoom impossible?

like image 296
rem Avatar asked Jan 13 '10 20:01

rem


2 Answers

General rule

With few exceptions, everything in WPF can be panned, zoomed, rotated, stretched, etc to your heart's content. This include single controls like Button, compound controls like ListBox, and containers like StackPanel.

The exceptions

Here are the exceptions:

  1. If you are using Adorner and your AdornerDecorator is outside the panned/zoomed area, then the Adorners attached to your panned/zoomed area will pan but not zoom. The solution is to put an additional AdornerDecorator inside the panned/zoomed area.

  2. If you use a Popup, it will display at the panned/zoomed location of its PlacementTarget but it will not itself be scaled. It will also not move as you pan the area containing its PlacementTarget (basically it sits in its own surface above the target control). To get around this, use a zero-size Canvas with high Z order instead when you want something to pop up within the zoom/pan area.

  3. Any ContextMenu you define will be shown inside a popup, so the menu items will display normal size even when the area you clicked on is zoomed in or out. Because of the nature of a context menu, this is probably desirable behavior. If not, you can wrap the menu items in a ViewBox and tie the zoom to your main area's zoom.

  4. Your ToolTips will display normal size even if the UI is panned or zoomed. Same solution as for ContextMenu.

  5. If you used WinForms integration to integrated legacy WinForms controls and UI, they will not properly pan, zoom and clip in certain situations. There is an advanced technique for working around this, where you implement the WinForms control off-screen, then using BitBlt or similar copy the image into your window as an image, and forward mouse clicks and keystrokes to the offscreen window. This is a lot of work, though.

  6. If you bypass WPF and directly use GDI+ or DirectX, or use Win32 hWnds to display content or UI, that content or UI will not be properly panned, zoomed or clipped to the window unless you do it yourself in your interface code.

Final notes

  • A good WPF UI always uses panels like Grid, DockPanel, etc to lay out controls in a flexible manner so they automatically adjust to container sizes, rather than using fixed sizes and positions. This is also true for the internal contents of your pan/zoom area as well, BUT there is an exception to this rule: the outermost element in your pan/zoom area must have a specified size. Otherwise what will define the area being panned/zoomed over?

  • The easy way to implement pan/zoom capabilities is to adjust the RenderTransform of the outermost control in your pan/zoom area. There are many different ways to implement controls for panning and zooming, for example you could use toolbar buttons and sliders, scroll bars, mouse wheel, spacebar+drag to pan, draggable areas of panned UI itself, or any combination of these. Whichever interface you choose, just have it update the RenderTransform appropriately from the code-behind and you're good to go.

  • If your chosen panning mechanism is scroll bars, you might want to use a ScrollViewer and only use the RenderTransform for the zoom.

  • Be sure you set clipping on the pan/zoom area. Otherwise if you zoom in or pan items off the side, they will still be visible outside the pan/zoom area.

like image 114
Ray Burns Avatar answered Sep 20 '22 02:09

Ray Burns


Use a MultiScaleImage or Canvas area, and place everything you need to pan and zoom in it

<Canvas x:Name="panZoomPanel" Background="Transparent">
</Canvas>

In code use make a TranslateTransform and a ScaleTransform in a TransformGroup to pan and zoom

Check out other SO post or this example or this one

like image 31
TFD Avatar answered Sep 22 '22 02:09

TFD