WPF中文网

行为之控件移动效果

关于控件的平移,我们之前学习转换时,曾经对TranslateTransform进行了讲解和示例。在那个示例中,我们只需要设置TranslateTransform的X属性和Y属性,使可以移动一个控件的位置。在学习了行为之后,我们肯定不希望一遍又一遍地去实现控件的移动效果,如果将移动效果做成一个行为,那么,任何一个控件,只要想拥有移动效果,直接调用行为即可,岂不快哉。

实现思路:

1、TranslateTransform平移对象最终赋值给RenderTransform属性,而RenderTransform位于UIElement基类中,所以,行为的泛型T参数应设置为UIElement。

2、TranslateTransform的X和Y是当前控件平移的位置坐标,这个坐标相对于当前控件的父控件而言的,所以在实现行为时,要拿到这个父控件。

3、我们采用鼠标去拖拽一个控件进行平移,所以要获取鼠标按下时的位置和移动过程中的位置,从而才知道TranslateTransform要平移到什么位置。

4、如果当前被移动的控件没有TranslateTransform,我们需要先给它实例化一个TranslateTransform对象。

根据上面的思路,我们来实现这个移动行为。

public class DragBehavior : Behavior<FrameworkElement>
{
    protected bool isDragging = false;
    private Point startPosition;

    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.MouseDown += AssociatedObject_MouseDown;
        AssociatedObject.MouseMove += AssociatedObject_MouseMove;
        AssociatedObject.MouseUp += AssociatedObject_MouseUp;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.MouseDown -= AssociatedObject_MouseDown;
        AssociatedObject.MouseMove -= AssociatedObject_MouseMove;
        AssociatedObject.MouseUp -= AssociatedObject_MouseUp;
    }

    private void AssociatedObject_MouseDown(object sender, 
        System.Windows.Input.MouseButtonEventArgs e)
    {
        isDragging = true;
        var parent = AssociatedObject.Parent as FrameworkElement;
        var clickPosition = e.GetPosition(parent);

        //首次按下时,判断RenderTransform的类型是否为TranslateTransform
        if (!(AssociatedObject.RenderTransform is TranslateTransform))
        { 
            AssociatedObject.RenderTransform = new TranslateTransform(); 
        }

        var transform = AssociatedObject.RenderTransform as TranslateTransform;
        startPosition.X = clickPosition.X - transform.X;   
        startPosition.Y = clickPosition.Y - transform.Y;
        AssociatedObject.CaptureMouse();//强制鼠标捕捉
    }

    private void AssociatedObject_MouseMove(object sender, 
        System.Windows.Input.MouseEventArgs e)
    {
        if (isDragging)
        {
            var parent = AssociatedObject.Parent as FrameworkElement;
            Point currentPosition = e.GetPosition(parent);
            var transform = AssociatedObject.RenderTransform as TranslateTransform;

            transform.X = currentPosition.X - startPosition.X;
            transform.Y = currentPosition.Y - startPosition.Y;
        }
    }
    private void AssociatedObject_MouseUp(object sender, 
        System.Windows.Input.MouseButtonEventArgs e)
    {
        isDragging = false;
        AssociatedObject.ReleaseMouseCapture();//释放鼠标捕捉
    }
}

下一步,我们在需要移动的控件上引用这个行为。

<Window x:Class="HelloWorld.MainWindow"
        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:HelloWorld" 
        xmlns:controls="clr-namespace:HelloWorld.Controls"
        xmlns:helper="clr-namespace:HelloWorld.MVVM" 
        xmlns:i="http://schemas.microsoft.com/xaml/behaviors" 
        xmlns:behavior="clr-namespace:HelloWorld.Behaviors"
        mc:Ignorable="d" Background="DarkCyan"
        Title="WPF中文网 - 行为 - www.wpfsoft.com" Height="350" Width="500">
    <Window.DataContext>
        <local:MainViewModel/>
    </Window.DataContext>
    <Canvas>
        <Border Width="50" Height="50" CornerRadius="50" 
                Background="LightGoldenrodYellow" 
                Canvas.Left="228" Canvas.Top="20">
            <i:Interaction.Behaviors>
                <behavior:ShadowBehavior/>
                <behavior:DragBehavior/>
            </i:Interaction.Behaviors>
        </Border>
        <TextBlock Text="WPF中文网" 
                   Foreground="White" 
                   FontSize="60" 
                   Canvas.Left="92" 
                   Canvas.Top="75">
            <i:Interaction.Behaviors>
                <behavior:ShadowBehavior/>
                <behavior:DragBehavior/>
            </i:Interaction.Behaviors>
        </TextBlock>
        <TextBlock Text="Behavior行为之阴影效果" 
                   Foreground="White" 
                   FontSize="40" 
                   Canvas.Left="21" 
                   Canvas.Top="182">
            <i:Interaction.Behaviors>
                <behavior:ShadowBehavior/>
                <behavior:DragBehavior/>
            </i:Interaction.Behaviors>
        </TextBlock>
        <Button Content="退出" Width="80" Height="30" 
                FontSize="14"
                Canvas.Left="375" Canvas.Top="265">
            <i:Interaction.Behaviors>
                <behavior:ShadowBehavior/>
                <behavior:DragBehavior/>
            </i:Interaction.Behaviors>
        </Button>
    </Canvas>
</Window>

这是鼠标移动之前的效果。

这是鼠标随意移动之后的效果。

当前课程源码下载:(注明:本站所有源代码请按标题搜索)

文件名:108-《行为之控件移动效果》-源代码
链接:https://pan.baidu.com/s/1yu-q4tUtl0poLVgmcMfgBA
提取码:wpff

——重庆教主 2023年11月21日

copyright @重庆教主 WPF中文网 联系站长:(QQ)23611316 (微信)movieclip (QQ群).NET小白课堂:864486030 | 本文由WPF中文网原创发布,谢绝转载 渝ICP备2023009518号-1