【WPF】自定义Canvas控件实现添加控件画图、缩放功能
1.xaml布局文件
<UserControl
x:Class="Controls.UserControls.CanvasUserControl"
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:local="clr-namespace:JieJun.Controls.UserControls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
d:DesignHeight="640"
d:DesignWidth="768"
mc:Ignorable="d">
<Grid x:Name="Grid_Content" ClipToBounds="True">
<Canvas
x:Name="myCanvas"
Width="{Binding ElementName=Grid_Content, Path=ActualWidth}"
Height="{Binding ElementName=Grid_Content, Path=ActualHeight}"
Background="Black"
MouseLeftButtonDown="myCanvas_MouseLeftButtonDown"
MouseLeftButtonUp="myCanvas_MouseLeftButtonUp"
MouseMove="myCanvas_MouseMove"
MouseRightButtonDown="myCanvas_MouseRightButtonDown"
MouseWheel="myCanvas_MouseWheel">
<Canvas.RenderTransform>
<TransformGroup>
<!-- 缩放 -->
<ScaleTransform x:Name="CanvasScaleTransform" CenterX="0" CenterY="0" ScaleX="1" ScaleY="-1" />
<!-- 平移 -->
<TranslateTransform x:Name="CanvasTranslateTransform" X="0" Y="{Binding ActualHeight, ElementName=myCanvas}" />
<!-- Y轴翻转 -->
<ScaleTransform ScaleY="-1" />
<!-- 原点对齐 -->
<TranslateTransform Y="{Binding ActualHeight, ElementName=myCanvas}" />
</TransformGroup>
</Canvas.RenderTransform>
</Canvas>
</Grid>
</UserControl>
2.后台代码实现
/// <summary>
/// CanvasUserControl.xaml 的交互逻辑
/// </summary>
public partial class CanvasUserControl : UserControl
{
private Point _lastMousePosition;
private bool _isDragging;
private double InitScale = 1;//初始化比例
public CanvasUserControl()
{
InitializeComponent();
}
/// <summary>
/// 鼠标缩放
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void myCanvas_MouseWheel(object sender, MouseWheelEventArgs e)
{
try
{
// 计算缩放系数(每滚动一格缩放10%)
double zoomFactor = e.Delta > 0 ? 1.02 : 0.98;
// 限制缩放范围(0.1倍到10倍)
if (CanvasScaleTransform.ScaleX * zoomFactor < 0.1 || CanvasScaleTransform.ScaleX * zoomFactor > 30) return;
// 应用缩放
CanvasScaleTransform.ScaleX *= zoomFactor;
CanvasScaleTransform.ScaleY *= zoomFactor;
e.Handled = true;
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
/// <summary>
/// 鼠标左键按下
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void myCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
try
{
if (e.ChangedButton != MouseButton.Left) return;
_isDragging = true;
_lastMousePosition = e.GetPosition(this);
myCanvas.CaptureMouse();
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
/// <summary>
/// 鼠标左键放开
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void myCanvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
try
{
if(myCanvas.IsMouseCaptured)
{
_isDragging = false;
myCanvas.ReleaseMouseCapture();
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
/// <summary>
/// 鼠标移动
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void myCanvas_MouseMove(object sender, MouseEventArgs e)
{
try
{
if (!_isDragging) return;
if (e.LeftButton == MouseButtonState.Pressed)
{
Point currentPosition = e.GetPosition(this);
double deltaX = currentPosition.X - _lastMousePosition.X;
double deltaY = currentPosition.Y - _lastMousePosition.Y;
CanvasTranslateTransform.X += deltaX;
CanvasTranslateTransform.Y -= deltaY;
_lastMousePosition = currentPosition;
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
/// <summary>
/// 鼠标右键按下
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void myCanvas_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
Reset();
}
private void Reset()
{
try
{
CanvasScaleTransform.ScaleX = CanvasScaleTransform.ScaleY = InitScale;
CanvasTranslateTransform.X = CanvasTranslateTransform.Y = 0;
CanvasScaleTransform.CenterX = 0;
CanvasScaleTransform.CenterY = 0;
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
/// <summary>
/// 添加Children
/// </summary>
/// <param name="element"></param>
public void AddChildren(UIElement element)
{
try
{
this.myCanvas.Children.Add(element);
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
/// <summary>
/// 清空Children
/// </summary>
public void ClearChildren()
{
try
{
this.myCanvas.Children.Clear();
Reset();
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
/// <summary>
/// 初始缩放比率
/// </summary>
/// <param name="scale"></param>
public void Scale(double scale)
{
if (scale == 0)
return;
InitScale = 1 / scale;
CanvasScaleTransform.ScaleX = CanvasScaleTransform.ScaleY = 1 / scale;
}
}

浙公网安备 33010602011771号