http://msdn.microsoft.com/en-us/magazine/dd188700.aspx
I am learning this article. What I am thinking is to write something similar to Magnify in this sample.
For example, if user want to add a magnify to a control, it will add a mirror control to its root node. This mirror control will take a snapshot of current screen, and then use clip, transform to magnify the control. It sounds workable, isn’t it?
I have encountered following issues when implementing this:
1. I am using Canvas to adjust its layout. But after setting its scale, the position is not correct any more
2. I am using RenderTargetBitmap. However, it is disable in Silverlight.
I write a similar one in WPF. If any one who has any other idea to zoom the selected area, please let me know.
Write a Zoom control
Code
<UserControl x:Class="WpfApplication1.MagnifyControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300">
<Grid>
<Grid x:Name="LayoutRoot" >
<Canvas x:Name="ZoomCanvas" Visibility="Collapsed" >
<Canvas.RenderTransform>
<ScaleTransform CenterX="0" CenterY="0" ScaleX="4" ScaleY="4"/>
</Canvas.RenderTransform>
<Canvas.Clip>
<EllipseGeometry x:Name="Lens" Center="0,0" RadiusX="40" RadiusY="40" />
</Canvas.Clip>
<Canvas Canvas.Left="0" Canvas.Top="0" >
<Image x:Name="MirrorImage" Canvas.Left="0" Canvas.Top="0" />
</Canvas>
<Path Canvas.Left="0" Canvas.Top="0" Stroke="#808080" StrokeThickness="1">
<Path.Data>
<EllipseGeometry x:Name="LensBorder" Center="0,0" RadiusX="40" RadiusY="40" />
</Path.Data>
</Path>
</Canvas>
</Grid>
</Grid>
</UserControl>
Second, adding event handler
Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MagnifyControl.xaml
/// </summary>
public partial class MagnifyControl : UserControl
{
private bool _dragging = false;
private const double _scale = 4.0;
Canvas _parentCanvas = null;
Canvas _mirrorCanvas = null;
Grid _topGrid = null;
public MagnifyControl()
{
InitializeComponent();
}
public void WireUp(Canvas parent, Canvas mirror, Grid topGrid)
{
_parentCanvas = parent;
_mirrorCanvas = mirror;
_topGrid = topGrid;
parent.Children.Add(this);
_mirrorCanvas.MouseLeftButtonDown += OnMouseLeftButtonDown;
_mirrorCanvas.MouseLeftButtonUp += OnMouseLeftButtonUp;
_mirrorCanvas.MouseMove += OnMouseMove;
}
private void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
//get the size of the printer page
RenderTargetBitmap bmp = new RenderTargetBitmap(Convert.ToInt16(_parentCanvas.ActualWidth), Convert.ToInt16(_parentCanvas.ActualHeight),
120, 96, PixelFormats.Pbgra32);
bmp.Render(_mirrorCanvas);
MirrorImage.Source = bmp;
double x = e.GetPosition(_parentCanvas).X;
double y = e.GetPosition(_parentCanvas).Y;
PositionLens(x, y);
ZoomCanvas.Visibility = Visibility.Visible;
((FrameworkElement)sender).CaptureMouse();
_dragging = true;
}
private void OnMouseMove(object sender, MouseEventArgs e)
{
if (_dragging)
{
double x = e.GetPosition(_mirrorCanvas).X;
double y = e.GetPosition(_mirrorCanvas).Y;
PositionLens(x, y);
}
}
private void OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (_dragging)
{
ZoomCanvas.Visibility = Visibility.Collapsed;
((FrameworkElement)sender).ReleaseMouseCapture();
_dragging = false;
}
}
private void PositionLens(double x, double y)
{
Lens.Center = LensBorder.Center = new Point(x, y);
this.SetValue(Canvas.LeftProperty, (1 - _scale) * x);
this.SetValue(Canvas.TopProperty, (1 - _scale) * y);
}
}
}
Sample to use this control:
MagnifyControl magnify = new MagnifyControl();
magnify.WireUp(RootCanvas, MainCanvas, LayoutRoot);