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

相关推荐
闻缺陷则喜何志丹3 小时前
【C# WPF】TextBox的数据绑定
ui·c#·wpf·mvvm·数据绑定·textbox
码农水水1 天前
得物Java面试被问:大规模数据的分布式排序和聚合
java·开发语言·spring boot·分布式·面试·php·wpf
时光慢煮1 天前
行走在多端之间:基于 Flutter × OpenHarmony 的旅行记录应用实践 —— 旅行详情查看模块解析
flutter·华为·开源·wpf·openharmony
xiaobaishuoAI2 天前
分布式事务实战(Seata 版):解决分布式系统数据一致性问题(含代码教学)
大数据·人工智能·分布式·深度学习·wpf·geo
小北方城市网2 天前
微服务注册中心与配置中心实战(Nacos 版):实现服务治理与配置统一
人工智能·后端·安全·职场和发展·wpf·restful
cjp5602 天前
017.WPF使用自定义样式
wpf
故事不长丨2 天前
C#log4net详解:从入门到精通,配置、实战与框架对比
c#·.net·wpf·log4net·日志·winform·日志系统
cjp5602 天前
002.为C#动态链接库添加wpf窗体
microsoft·c#·wpf
bugcome_com2 天前
WPF控件模板
wpf
上海物联网3 天前
Prism WPF中的自定义区域适配器解决了什么问题?在项目中怎么实现一个自定义适配器
wpf