WPF 控件的缩放和移动

WPF 控件的缩放和移动

1.页面代码

xml 复制代码
<ContentControl ClipToBounds="True" Cursor="SizeAll">
     <Viewbox
         x:Name="viewbox"
         MouseDown="viewbox_MouseDown"
         MouseMove="viewbox_MouseMove"
         MouseWheel="Viewbox_MouseWheel">
         <Viewbox.RenderTransform>
             <TransformGroup>
                 <!--  将下面的三种转换组合到一起  -->
                 <ScaleTransform x:Name="scaler"/>
                 <TranslateTransform x:Name="transer" />
             </TransformGroup>
         </Viewbox.RenderTransform>
         <Image Name="image" Source="{Binding ImageSource, RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}}" />
     </Viewbox>
 </ContentControl>

ScaleTransform 用于进行缩放

TranslateTransform 用于进行位置的移动

ViewBox中可以放入不同的控件不光可以是图片

ContentControl 可以对超过容器的部分进行剪切,这样就不会覆盖到其他控件了

2.后台代码

csharp 复制代码
public partial class ImageSuper : UserControl
{
    public ImageSuper()
    {
        InitializeComponent();
    }

    public ImageSource ImageSource
    {
        get { return (ImageSource)GetValue(ImageSourceProperty); }
        set { SetValue(ImageSourceProperty, value); }
    }
    public static readonly DependencyProperty ImageSourceProperty =
        DependencyProperty.Register("ImageSource", typeof(ImageSource), typeof(ImageSuper), null);

    public double Scale
    {
        get { return (double)GetValue(ScaleProperty); }
        set { SetValue(ScaleProperty, value); }
    }
    public static readonly DependencyProperty ScaleProperty =
        DependencyProperty.Register("Scale", typeof(double), typeof(ImageSuper),
            new PropertyMetadata(default(double), new PropertyChangedCallback(ScalePropertyChanged)));
    public double TranserX
    {
        get { return (double)GetValue(TranserXProperty); }
        set { SetValue(TranserXProperty, value); }
    }
    public static readonly DependencyProperty TranserXProperty =
        DependencyProperty.Register("TranserX", typeof(double), typeof(ImageSuper),
            new PropertyMetadata(default(double), new PropertyChangedCallback(TranserPropertyChanged)));
    public double TranserY
    {
        get { return (double)GetValue(TranserYProperty); }
        set { SetValue(TranserYProperty, value); }
    }
    public static readonly DependencyProperty TranserYProperty =
        DependencyProperty.Register("TranserY", typeof(double), typeof(ImageSuper),
            new PropertyMetadata(default(double), new PropertyChangedCallback(TranserPropertyChanged)));

    public static void ScalePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        (d as ImageSuper).DoScale();
    }
    public static void TranserPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        (d as ImageSuper).DoMove();
    }

    /// <summary>
    /// 缩放图片。最小为0.1倍,最大为0倍
    /// </summary>
    private void DoScale()
    {
        // 限制最大、最小缩放倍数
        if (scaler.ScaleX + Scale < 0.1 || scaler.ScaleX + Scale > 80) return;

        scaler.ScaleX = Scale;
        scaler.ScaleY = Scale;
    }

    /// <summary>
    /// 移动图片
    /// </summary>
    private void DoMove()
    {
        transer.X = TranserX;
        transer.Y = TranserY;
    }

    
    private void Viewbox_MouseWheel(object sender, MouseWheelEventArgs e)
    {
        var point = e.GetPosition(viewbox);
        var delta = e.Delta * 0.002;
        Scale += delta;
        TranserX -= point.X * delta;
        TranserY -= point.Y * delta;
    }

    private Point lastMousePosition;
    private void viewbox_MouseDown(object sender, MouseButtonEventArgs e)
    {
        Point currentMousePosition = e.GetPosition(image);
        lastMousePosition = currentMousePosition;
    }

    private void viewbox_MouseMove(object sender, MouseEventArgs e)
    {
        if (e.LeftButton == MouseButtonState.Pressed)
        {
            // 获取鼠标相对于图片的位置
            Point currentMousePosition = e.GetPosition(image);

            // 获取鼠标在X轴和Y轴上的移动距离
            double deltaX = currentMousePosition.X - lastMousePosition.X;
            double deltaY = currentMousePosition.Y - lastMousePosition.Y;

            TranserX += deltaX / 10;
            TranserY += deltaY / 10;
        }
    }
}

3.总结

目前这个是直接做成了第三方控件的样式使用的,还有一个旋转的属性但是因为项目不需要所有就没有加进去.还有一个自适应大小的功能就是把Scale 的值改为1,TranserX 和TranserY 的值改为0就可以了.

2023/11/20

相关推荐
军训猫猫头17 小时前
7.带输入参数的线程启动 C# + WPF 完整示例
开发语言·前端·c#·.net·wpf
周杰伦fans1 天前
WPF Prism 框架完全入门指南:从环境搭建到弹窗导航实战
wpf
雨浓YN1 天前
WPF MVVM 模式(无调库)项目创建笔记
笔记·wpf
周杰伦fans2 天前
.NET AOT技术深度解析:为什么WPF不支持而Avalonia/UWP支持?
.net·wpf
雨浓YN2 天前
WPF MVVM 模式(调Prism库)项目创建笔记 —— 包含C++/CLI OpenCV互操作
c++·笔记·wpf
七夜zippoe2 天前
DolphinDB数据模型:表、分区与分布式表
分布式·wpf·数据模型··dolphindb
一念春风2 天前
Qwen2.5 (AI模型 PC搭建)
人工智能·ai·c#·wpf·模型
互联网散修3 天前
鸿蒙跨设备实时绘图同步:从零到一实现分布式画板
分布式·wpf·harmonyos
晓纪同学3 天前
WPF-09 命令系统
wpf
晓纪同学4 天前
WPF-10资源系统
wpf