Avalonia 实现平滑拖动指定控件

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Avalonia 实现平滑拖动指定控件相关的知识,希望对你有一定的参考价值。

Avalonia 实现平滑拖动指定控件

1.创建一个UserControl控件,并且添加以下代码

using System;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Markup.Xaml;
using Avalonia.Media;
using Avalonia.Media.Imaging;
using Avalonia.Platform;
using Avalonia.Threading;
using Avalonia.VisualTree;

namespace Token;

/// <summary>
/// 实现拖动的控件
/// </summary>
public partial class DragControls : UserControl

    /// <summary>
    /// 记录上一次鼠标位置
    /// </summary>
    private Point lastMousePosition;

    /// <summary>
    /// 用于平滑更新坐标的计时器
    /// </summary>
    private DispatcherTimer _timer;

    /// <summary>
    /// 标记是否先启动了拖动
    /// </summary>
    private bool isDragging = false;

    /// <summary>
    /// 需要更新的坐标点
    /// </summary>
    private PixelPoint _targetPosition;

    public LoginStackPanelRight()
    
        InitializeComponent();

        // 添加当前控件的事件监听
        PointerPressed += OnPointerPressed;
        PointerMoved += OnPointerMoved;
        PointerReleased += OnPointerReleased;

        // 初始化计时器
        _timer = new DispatcherTimer
        
            Interval = TimeSpan.FromMilliseconds(10)
        ;
        _timer.Tick += OnTimerTick;
    

    /// <summary>
    /// 计时器事件
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void OnTimerTick(object sender, EventArgs e)
    
        var window = this.FindAncestorOfType<Window>();
        if (window != null && window.Position != _targetPosition)
        
            // 更新坐标
            window.Position = _targetPosition;
        
    

    private void InitializeComponent()
    
        AvaloniaXamlLoader.Load(this);
    

    private void OnPointerPressed(object sender, PointerPressedEventArgs e)
    
        if (!e.GetCurrentPoint(this).Properties.IsLeftButtonPressed) return;
        // 启动拖动
        isDragging = true;
        // 记录当前坐标
        lastMousePosition = e.GetPosition(this);
        e.Handled = true;
        // 启动计时器
        _timer.Start();
    

    private void OnPointerReleased(object sender, PointerReleasedEventArgs e)
    
        if (!isDragging) return;
        // 停止拖动
        isDragging = false;
        e.Handled = true;
        // 停止计时器
        _timer.Stop();
    

    private void OnPointerMoved(object sender, PointerEventArgs e)
    
        if (!e.GetCurrentPoint(this).Properties.IsLeftButtonPressed) return;
        
        // 如果没有启动拖动,则不执行
        if (!isDragging) return;

        var currentMousePosition = e.GetPosition(this);
        var offset = currentMousePosition - lastMousePosition;
        var window = this.FindAncestorOfType<Window>();
        if (window != null)
        
            // 记录当前坐标
            _targetPosition = new PixelPoint(window.Position.X + (int)offset.X,
                window.Position.Y + (int)offset.Y);
        
    

通过以上组件可以实现平滑拖动 效果如图

来着token的分享

以上是关于Avalonia 实现平滑拖动指定控件的主要内容,如果未能解决你的问题,请参考以下文章

Avalonia跨平台入门第十三篇之Expander控件

在 Avalonia 中实现 TreeView 节点的拖放

一起学习Avalonia(九)

Avalonia跨平台入门第十篇之控件的锁定

Avalonia跨平台入门第八篇之控件的拖放

Avalonia跨平台入门第十二篇之动画效果