Last active
September 17, 2016 14:14
-
-
Save earthengine/0a6825379204addf0313a010c3d8877c to your computer and use it in GitHub Desktop.
A WPF control that can zoom in and positioning its content by mouse
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<UserControl x:Class="WPFZoomText.ZoomViewer" | |
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |
xmlns:local="clr-namespace:WPFZoomText" | |
mc:Ignorable="d" | |
d:DesignHeight="500" d:DesignWidth="500"> | |
<Grid Background="Black" MouseDown="Grid_MouseDown" MouseUp="Grid_MouseUp" MouseWheel="Grid_MouseWheel" | |
SizeChanged="Grid_SizeChanged"> | |
<Canvas Name="canvas" Canvas.Left="0" Canvas.Top="0"> | |
<Canvas.RenderTransform> | |
<MatrixTransform x:Name="scale" /> | |
</Canvas.RenderTransform> | |
</Canvas> | |
</Grid> | |
</UserControl> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Windows; | |
using System.Windows.Controls; | |
using System.Windows.Input; | |
using System.Windows.Media; | |
namespace WPFZoomText | |
{ | |
/// <summary> | |
/// Interaction logic for ZoomViewer.xaml | |
/// </summary> | |
public partial class ZoomViewer : UserControl | |
{ | |
/// <summary> | |
/// Default constructor. | |
/// </summary> | |
public ZoomViewer() | |
{ | |
InitializeComponent(); | |
} | |
public Rect Domain { get; set; } = new Rect() { X = 0, Y = 0, Width = 30, Height = 30 }; | |
/// <summary> | |
/// The set of the inner drawings (scale will affect to those drawings) | |
/// </summary> | |
public UIElementCollection Drawings | |
{ | |
get | |
{ | |
return canvas.Children; | |
} | |
} | |
/// <summary> | |
/// Scale the content to show everything. | |
/// </summary> | |
public void ZoomFit() | |
{ | |
var s1 = ActualWidth / Domain.Width; | |
var s2 = ActualHeight / Domain.Height; | |
var m = new Matrix(); | |
var sc = s1 > s2 ? s2 : s1; | |
m.Scale(sc, sc); | |
var porig = m.Transform(new Point(Domain.Width / 2 + Domain.Left, Domain.Height / 2 + Domain.Top)); | |
var pdest = new Point(ActualWidth / 2, ActualHeight / 2); | |
m.Translate(pdest.X - porig.X, pdest.Y - porig.Y); | |
scale.Matrix = m; | |
} | |
private Point? draggingPoint = null; | |
private void Grid_MouseDown(object sender, MouseButtonEventArgs e) | |
{ | |
e.Handled = true; | |
if (e.ChangedButton == MouseButton.Left) | |
{ | |
if (e.ClickCount == 2) | |
{ | |
ZoomFit(); | |
} else | |
{ | |
draggingPoint = e.GetPosition(canvas); | |
((Grid)sender).CaptureMouse(); | |
} | |
} | |
} | |
private void Grid_MouseUp(object sender, MouseButtonEventArgs e) | |
{ | |
e.Handled = true; | |
if (e.ChangedButton == MouseButton.Left) { | |
if (draggingPoint.HasValue) | |
{ | |
var pos = e.GetPosition(canvas); | |
var v = draggingPoint.Value - pos; | |
var m = scale.Matrix; | |
m.Translate(-v.X, -v.Y); | |
scale.Matrix = m; | |
((Grid)sender).ReleaseMouseCapture(); | |
draggingPoint = null; | |
} | |
} | |
} | |
private void Grid_MouseWheel(object sender, MouseWheelEventArgs e) | |
{ | |
e.Handled = true; | |
var s = e.Delta > 0 ? 1.04 : 0.96; | |
var m = scale.Matrix; | |
var porig = m.Transform(e.GetPosition(canvas)); | |
m.ScaleAt(s, s, porig.X, porig.Y); | |
scale.Matrix = m; | |
} | |
private void Grid_SizeChanged(object sender, SizeChangedEventArgs e) | |
{ | |
ZoomFit(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment