Avalonia 可视化图形坐标和鼠标位置通用转换方法
Avalonia 可视化图形坐标和鼠标位置通用转换方法
零、前言与示例场景
在进行一些画布编辑的应用开发的时候,获得控件的相对位置是一个很重要的点。
本文希望能够介绍一些获得控件位置的办法,供各位参考一二。
测试场景如下,在画布上的(50,50)处有一个尺寸为(100,100)的橙色矩形,其中画布具有 10 的边距:

具体的布局内容如下:
<UserControl
x:Class="MyAvaloniaTestArea.Views.MainView"
xmlns="https://github.com/avaloniaui"
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:vm="clr-namespace:MyAvaloniaTestArea.ViewModels"
d:DesignHeight="450"
d:DesignWidth="800"
x:DataType="vm:MainViewModel"
Background="Gray"
mc:Ignorable="d">
<Design.DataContext>
<!--
This only sets the DataContext for the previewer in an IDE,
to set the actual DataContext for runtime, set the DataContext property in code (look at App.axaml.cs)
-->
<vm:MainViewModel />
</Design.DataContext>
<Canvas
Name="PART_Canvas"
Margin="10"
Background="White">
<Rectangle
Name="PART_Rectangle"
Canvas.Left="50"
Canvas.Top="50"
Width="100"
Height="100"
Fill="Orange" />
</Canvas>
</UserControl>
一、鼠标相关事件在对应控件上时,事件中获得的坐标是相对于控件的

本人依次点击了矩形的四个角落,得到了以下的输出:
rectangle pointer pressed 6, 7
rectangle pointer pressed 7, 87
rectangle pointer pressed 86, 87
rectangle pointer pressed 90, 5
具体测试的代码如下:
<Rectangle
Name="PART_Rectangle"
Canvas.Left="50"
Canvas.Top="50"
Width="100"
Height="100"
Fill="Orange"
PointerPressed="Rectangle_PointerPressed" />
private void Rectangle_PointerPressed(object? sender, Avalonia.Input.PointerPressedEventArgs e)
{
var rectangle = sender as Rectangle;
var currentPointer = e.GetCurrentPoint(rectangle);
Debug.WriteLine($"rectangle pointer pressed {currentPointer.Position}");
}
用处:可以在实现图形的拖拽时,提前保留图形拖拽点的位置,在进行移动的时候,保证鼠标能够一直抓住拖拽的起点,不至于在移动时突然鼠标抓住的点变成图形的左上角。
二、调用 GetCurrentPoint() 时传入不同的参考对象,会得到给予对应参考对象的相对坐标
private void Rectangle_PointerPressed(object? sender, Avalonia.Input.PointerPressedEventArgs e)
{
var currentPointer = e.GetCurrentPoint(PART_Canvas);
Debug.WriteLine($"canvas pointer pressed {currentPointer.Position}");
}
canvas pointer pressed 57, 61
canvas pointer pressed 57, 135
canvas pointer pressed 135, 136
canvas pointer pressed 136, 64
用处:画布很适合当一个固定参考系,在进行一些画布处理的时候,即使当前事件并不是由画布移动触发的,还是能够更方便的拿到当前鼠标在画布的位置,用来做一些后续处理,比如点击此处在画布上创建图形等场景会有作用。
三、使用扩展方法 TranslatePoint() 进行参考系的转换
// 矩形的左上角在画布的哪个位置?
var pointBasedOnCanvas = PART_Rectangle.TranslatePoint(new Point(), PART_Canvas);
Debug.WriteLine($"point base on canvas {pointBasedOnCanvas}");
point base on canvas 50, 50
你可以看到,即使使用的是 Canvas.Left 和 Canvas.Top 进行了对图形的修改,但是实际上使用 TranslatePoint() 也可以忠实反应出图形的位置。
用处:一个很兼容的方法,系统自带的相对转换比自己写轮子要可靠。

浙公网安备 33010602011771号