Zoom
Le premier canvas doit être clippé et transparent. Quant au second, il contiendra tous les éléments à afficher. C'est sur ce dernier que les transformations de zoom seront appliquées.
|
<Canvas ClipToBounds="True" Background="Transparent">
<Canvas Name="petitCanvas">
...
</Canvas>
</Canvas>
|
Zoom roulette
|
void MainWindow_MouseWheel(object sender, MouseWheelEventArgs e)
{
double ratio = (e.Delta > 0) ? 1.1 : 0.9; // zoom in ou zoom out
var matrix = petitCanvas.RenderTransform.Value;
var grandCanvas = (FrameworkElement)petitCanvas.Parent;
matrix.ScaleAt(ratio, ratio, grandCanvas.ActualWidth / 2d, grandCanvas.ActualHeight / 2d);
petitCanvas.RenderTransform = new MatrixTransform(matrix);
}
|
Zoom avec rectangle de sélection
|
void MainWindow_MouseDown(object sender, MouseButtonEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{ // dessin du rectangle de sélection
_selection = new Rectangle();
_selection.Stroke = Brushes.Blue;
Brush fillBrush = Brushes.Blue.Clone();
fillBrush.Opacity = 0.2d;
_selection.Fill = fillBrush;
_selection.StrokeThickness = 1;
petitCanvas.Children.Add(_selection);
_originOfSelection = e.GetPosition(petitCanvas);
Canvas.SetLeft(_selection, _originOfSelection.X);
Canvas.SetTop(_selection, _originOfSelection.Y);
petitCanvas.CaptureMouse();
}
}
void MainWindow_MouseMove(object sender, MouseEventArgs e)
{
if (_selection != null)
{ // changement de taille du rectangle de sélection
var position = e.GetPosition(petitCanvas);
Canvas.SetLeft(_selection, Math.Min(p.X, _originOfSelection.X));
Canvas.SetTop(_selection, Math.Min(p.Y, _originOfSelection.Y));
_selection.Width = Math.Abs(p.X - _originOfSelection.X);
_selection.Height = Math.Abs(p.Y - _originOfSelection.Y);
}
}
void MainWindow_MouseUp(object sender, MouseButtonEventArgs e)
{
if (selection != null)
{
Rect selectionRect = new Rect(
Canvas.GetLeft(selection), Canvas.GetTop(selection),
selection.Width, selection.Height);
ZoomFit(selectionRect);
petitCanvas.Children.Remove(selection);
selection = null;
petitCanvas.ReleaseMouseCapture();
}
}
public void ZoomFit(Rect sourceRect)
{
var grandCanvas = (FrameworkElement)petitCanvas.Parent;
var destinationSize = new Size(grandCanvas.ActualWidth, grandCanvas.ActualHeight);
double w = destinationSize.Width / sourceRect.Width;
double h = destinationSize.Height / sourceRect.Height;
double ratio = Math.Min(w, h);
double dx = -(sourceRect.Left + sourceRect.Width / 2);
double dy = -(sourceRect.Top + sourceRect.Height / 2);
var matrix = new Matrix();
matrix.Translate(dx, dy);
matrix.Scale(ratio, ratio);
matrix.Translate(destinationSize.Width / 2, destinationSize.Height / 2);
petitCanvas.RenderTransform = new MatrixTransform(matrix);
}
|
Zoom contenu
|
// GetDescendantBounds renvoit le plus petit rectangle
// contenant l'ensemble des éléments de petitCanvas
ZoomFit(VisualTreeHelper.GetDescendantBounds(petitCanvas));
|
Déplacement du petit canvas
|
void MainWindow_MouseDown(object sender, MouseButtonEventArgs e)
{
if (e.MiddleButton == MouseButtonState.Pressed)
{
_originOfMove = e.GetPosition((FrameworkElement)petitCanvas.Parent);
_canStartMove = true;
}
}
void MainWindow_MouseMove(object sender, MouseEventArgs e)
{
if (_canStartMove)
{
var nextOrigin = e.GetPosition((FrameworkElement)petitCanvas.Parent);
var matrix = petitCanvas.RenderTransform.Value;
var v = nextOrigin - _originOfMove;
matrix.Translate(v.X, v.Y);
petitCanvas.RenderTransform = new MatrixTransform(matrix);
_originOfMove = nextOrigin;
}
}
void MainWindow_MouseUp(object sender, MouseButtonEventArgs e)
{
_canStartMove = false;
}
|