Avalonia 实现平滑拖动指定控件

简介: 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的分享

目录
相关文章
|
消息中间件 XML 网络协议
『NLog』.Net使用NLog使用方式及详细配置(输出至文件/RabbitMQ/远程网络Tcp)
📣读完这篇文章里你能收获到 - Nlog输出至文件/RabbitMQ/远程网络Tcp配置文档 - Nlog配置参数详解 - .NET CORE项目接入
6786 0
『NLog』.Net使用NLog使用方式及详细配置(输出至文件/RabbitMQ/远程网络Tcp)
|
Linux C# Android开发
.NET Avalonia开源、免费的桌面UI库 - SukiUI
.NET Avalonia开源、免费的桌面UI库 - SukiUI
1180 5
|
JSON 数据格式 开发者
Avalonia开源控件库强力推荐-Semi.Avalonia
Semi.Avalonia是以MIT协议开源的Avalonia UI框架下的Semi Design主题风格实现,搭配Ursa.Avalonia自定义控件库,为开发者带来全新视觉与功能体验。
Avalonia开源控件库强力推荐-Semi.Avalonia
|
机器学习/深度学习 人工智能 自然语言处理
一分钟认识:claude中文版_claude官网中文版
Claude AI 是由 Anthropic 开发的一款先进的对话式人工智能模型,它的名字来源于信息论之父——克劳德·香农 🧙‍♂️。
|
开发框架 JavaScript 前端开发
提升生产力:8个.NET开源且功能强大的快速开发框架
提升生产力:8个.NET开源且功能强大的快速开发框架
1024 3
|
SQL 关系型数据库 MySQL
云服务器 ECS产品使用问题之出现“1044 - Access denied for user ‘root‘@‘%‘ to database ‘数据库名称‘”这样的错误,该怎么办
云服务器ECS(Elastic Compute Service)是各大云服务商阿里云提供的一种基础云计算服务,它允许用户租用云端计算资源来部署和运行各种应用程序。以下是一个关于如何使用ECS产品的综合指南。
|
开发框架 .NET API
如何在 ASP.NET Core Web Api 项目中应用 NLog 写日志?
如何在 ASP.NET Core Web Api 项目中应用 NLog 写日志?
909 0
AvaloniaUI 取消标题栏,无边框无最大最小化,
AvaloniaUI 取消标题栏,无边框无最大最小化,
1866 1
AvaloniaUI 取消标题栏,无边框无最大最小化,