【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;
     }

 }

你可能感兴趣的:(wpf)