WPF Canvas Zoom and Pan
Copy from https://github.com/SEilers/WpfPanAndZoom
//canvas.xaml <Canvas x:Class="WpfApp69.CanvasZoomAndPanControl" 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:WpfApp69" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800" Background="#333333" MouseDown="Canvas_MouseDown" MouseUp="Canvas_MouseUp" MouseMove="Canvas_MouseMove" MouseWheel="Canvas_MouseWheel"> </Canvas> //xaml.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; 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 WpfApp69 { /// <summary> /// Interaction logic for CanvasZoomAndPanControl.xaml /// </summary> public partial class CanvasZoomAndPanControl : Canvas { private readonly MatrixTransform transform = new MatrixTransform(); private Point initialPosition; private bool dragging; private UIElement selectedElement; private Vector draggingDelta; private Color lineColor = Color.FromArgb(0xFF, 0x66, 0x66, 0x66); private Color backgroundColor = Color.FromArgb(0xFF, 0x33, 0x33, 0x33); private List<Line> gridLines = new List<Line>(); public CanvasZoomAndPanControl() { InitializeComponent(); BackgroundColor = backgroundColor; InitGridLines(); } private void InitGridLines() { for (int x = -4000; x <= 4000; x += 100) { Line verticalLine = new Line { Stroke = new SolidColorBrush(lineColor), X1 = x, Y1 = -4000, X2 = x, Y2 = 4000 }; if (x % 1000 == 0) { verticalLine.StrokeThickness = 6; } else { verticalLine.StrokeThickness = 2; } Children.Add(verticalLine); gridLines.Add(verticalLine); } for (int y = -4000; y <= 4000; y += 100) { Line horizontalLine = new Line { Stroke = new SolidColorBrush(lineColor), X1 = -4000, Y1 = y, X2 = 4000, Y2 = y }; if (y % 1000 == 0) { horizontalLine.StrokeThickness = 6; } else { horizontalLine.StrokeThickness = 2; } Children.Add(horizontalLine); gridLines.Add(horizontalLine); } } private void Canvas_MouseDown(object sender, MouseButtonEventArgs e) { if (e.ChangedButton == MouseButton.Right) { initialPosition = transform.Inverse.Transform(e.GetPosition(this)); } if (e.ChangedButton == MouseButton.Left) { if (this.Children.Contains((UIElement)e.Source)) { selectedElement = (UIElement)e.Source; Point mousePosition = Mouse.GetPosition(this); double x = Canvas.GetLeft(selectedElement); double y = Canvas.GetTop(selectedElement); Point elementPosition = new Point(x, y); draggingDelta = elementPosition - mousePosition; } dragging = true; } } private void Canvas_MouseUp(object sender, MouseButtonEventArgs e) { dragging = false; selectedElement = null; } private void Canvas_MouseMove(object sender, MouseEventArgs e) { if (e.RightButton == MouseButtonState.Pressed) { Point mousePosition = transform.Inverse.Transform(e.GetPosition(this)); Vector delta = Point.Subtract(mousePosition, initialPosition); var translate = new TranslateTransform(delta.X, delta.Y); transform.Matrix = translate.Value * transform.Matrix; foreach (UIElement child in this.Children) { child.RenderTransform = transform; } } if (dragging && e.LeftButton == MouseButtonState.Pressed) { double x = Mouse.GetPosition(this).X; double y = Mouse.GetPosition(this).Y; if (selectedElement != null) { Canvas.SetLeft(selectedElement, x + draggingDelta.X); Canvas.SetTop(selectedElement, y + draggingDelta.Y); } } } private void Canvas_MouseWheel(object sender, MouseWheelEventArgs e) { float scaleFactor = Zoomfactor; if (e.Delta < 0) { scaleFactor = 1f / scaleFactor; } Point mousePostion = e.GetPosition(this); Matrix scaleMatrix = transform.Matrix; scaleMatrix.ScaleAt(scaleFactor, scaleFactor, mousePostion.X, mousePostion.Y); transform.Matrix = scaleMatrix; foreach (UIElement child in this.Children) { double x = Canvas.GetLeft(child); double y = Canvas.GetTop(child); double sx = x * scaleFactor; double sy = y * scaleFactor; Canvas.SetLeft(child, sx); Canvas.SetTop(child, sy); child.RenderTransform = transform; } } public Color BackgroundColor { get { return backgroundColor; } set { backgroundColor = value; Background = new SolidColorBrush(backgroundColor); } } public float Zoomfactor { get; set; } = 1.1f; public Color LineColor { get { return lineColor; } set { lineColor = value; foreach(var line in gridLines) { line.Stroke=new SolidColorBrush(lineColor); } } } } } //MainWindow.xaml <Window x:Class="WpfApp69.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApp69" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <local:CanvasZoomAndPanControl> <Image RenderOptions.BitmapScalingMode="Fant" Stretch="Uniform" Source="Images/1.jpg"/> </local:CanvasZoomAndPanControl> </Window>
分类:
wpf
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
2022-12-18 cppconn cpp create table in cpp file ,show current date time in mysql cli via select current_timestamp command
2022-12-18 cppconn resultsetmetadata get columns count,get column name,resultset get value