在WPF中的Canvas上实现控件的拖动、缩放

本文介绍了如何在WPF环境中实现Canvas上自定义控件的拖动和缩放功能。通过分析Windows画图工具的行为,创建10个CustomThumb控件以区分不同的操作,并利用WPF的Thumb控件及其DragDelta和DragCompleted事件。通过自定义枚举标识操作意图,以及在构造函数和OnApplyTemplate中设置路由事件订阅,最终实现了一个可拖动和缩放的矩形框控件。
摘要由CSDN通过智能技术生成

   如题,项目中需要实现使用鼠标拖动、缩放一个矩形框,WPF中没有现成的,那就自己造一个轮子:)

   造轮子前先看看Windows自带的画图工具中是怎样做的,如下图:

 

   在被拖动的矩形框四周有9个小框,可以从不同方向拖动来放大缩小矩形框,另外需要注意的是,还有一个框,就是图中虚线的矩形框,这个框,是用来拖动目标控件的;我们要做的,就是模仿画图中的做法,在自定义控件中显示10个框,然后根据鼠标所在的框来处理鼠标输入,实现拖动与放大。

    参考这篇博文继续聊WPF——Thumb控件得知,WPF中有现成的拖动控件,可以提供对应的事件(DragDelta & DragCompleted), 就用它了。

还有一个需要考虑的是,我们的这个自定义控件中有10个不同作用的Thumb控件,如何区分事件从哪个Thumb发出来的呢?这样我们才能知道用户希望的操作是拖动,还是缩放,而且缩放也要知道朝哪个方向缩放。可以使用Tag属性,但是它是Object类型的,会涉及到拆箱,所以还是自定义一个CustomThumb。

    首先,定义说明拖动方向的枚举:

    public enum DragDirection
    {
        TopLeft = 1,
        TopCenter = 2,
        TopRight = 4,
        MiddleLeft = 16,
        MiddleCenter = 32,
        MiddleRight = 64,
        BottomLeft = 256,
        BottomCenter = 512,
        BottomRight = 1024,
    }

好了,有了这个枚举,就可以知道用户操作的意图了,现在自定义一个CustomThumb。

    public class CustomThumb : Thumb
    {
        public DragDirection DragDirection { get; set; }
    }
这些都弄好了,现在来写自定义控件的模板:

<ResourceDictionary 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:UICommon.Controls"
                    xmlns:Core="clr-namespace:System;assembly=mscorlib"
                    mc:Ignorable="d">


    
    <ControlTemplate TargetType="{x:Type local:DragHelperBase}" x:Key="DrapControlHelperTemplate">
        <ControlTemplate.Resources>
            <Style TargetType="{x:Type Thumb}" x:Key="CornerThumbStyle">
                <Setter Property="Width" Value="{Binding CornerWidth, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"/>
                <Setter Property="Height" Value="{Binding CornerWidth, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"/>
                <Setter Property="BorderBrush" Value="{Binding BorderBrush, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"/>
                <Setter Property="BorderThickness" Value="3"/>
                <Setter Property="Background" Value="Transparent"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type Thumb}">
                            <Border SnapsToDevicePixels="True"
                                    Width="{TemplateBinding Width}" 
						            Height="{TemplateBinding Height}"
						            Background="{TemplateBinding Background}" 
						            BorderBrush="{TemplateBinding BorderBrush}"
						            BorderThickness="{TemplateBinding BorderThickness}"/>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
            
            <Style TargetType="{x:Type Thumb}" x:Key="AreaThumbStyle">
                <Setter Property="BorderBrush" Value="{Binding BorderBrush, RelativeSource={RelativeSource TemplatedParent}}"/>
                <Setter Property="Background" Value="Transparent"/>
                <Setter Property="Padding" Value="0"/>
                <Setter Property="Margin" Value="0"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate T
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值