Skip to content

指针捕获(Pointer Capture) ​

允许控件捕获指针输入,使指针移动事件持续发送到捕获控件,即使指针移出控件区域。适用于拖拽、摇杆、滑块等交互。

定义位置:GameUI.Control.Control(部分类 Control.CapturePointer.cs)

API ​

方法(Control 成员) ​

csharp
void CapturePointer(PointerButtons pointerButtons);
void ReleasePointer(PointerButtons pointerButtons);

事件 ​

csharp
event EventHandler<PointerCapturedMoveEventArgs>? OnPointerCapturedMove;

捕获期间指针移动时触发。仅在 CapturePointer 之后、ReleasePointer 或指针释放之前有效。

PointerCapturedMoveEventArgs ​

继承 PointerEventArgs:

属性类型说明
PointerButtonsPointerButtons触发的按键
ButtonsOnControlPointerButtons控件上当前按下的按键
PointerPositionPointerPosition?指针位置
XfloatX 坐标
YfloatY 坐标
PositionVector2位置向量
HasPositionbool是否有有效位置

PointerButtons ​

[Flags] 枚举:None, Button1–Button32, All

手动模式 ​

csharp
control.OnPointerPressed += (s, e) =>
{
    control.CapturePointer(e.PointerButtons);
};

control.OnPointerCapturedMove += (s, e) =>
{
    if (e.HasPosition)
    {
        // 处理拖拽
        Game.Logger.LogInformation("拖拽位置: {X}, {Y}", e.X, e.Y);
    }
};

control.OnPointerReleased += (s, e) =>
{
    control.ReleasePointer(e.PointerButtons);
};

流式扩展 ​

BuilderExtensions 提供简化写法:

csharp
// CapturedMove — 订阅捕获移动事件
control.CapturedMove((PointerCapturedMoveEventArgs e) =>
{
    // 处理移动
});

// TrackPointer — 自动管理捕获/释放生命周期
control.TrackPointer((PointerCapturedMoveEventArgs e) =>
{
    if (e.PointerPosition.HasValue)
        control.Position = e.PointerPosition.Value;
});

TrackPointer 签名 ​

csharp
static T TrackPointer<T>(this T control, Action<PointerCapturedMoveEventArgs> onMove) where T : Control;
static T TrackPointer<T>(this T control, Action onMove) where T : Control;

TrackPointer 等效于手动在 OnPointerPressed 中调用 CapturePointer、订阅 OnPointerCapturedMove、在 OnPointerReleased 中调用 ReleasePointer。

典型场景 ​

拖拽控件 ​

csharp
var handle = new Label("拖动我");
handle.TrackPointer(e =>
{
    if (e.HasPosition)
    {
        handle.Margin = new Thickness(e.X, e.Y, 0, 0);
    }
});

自定义滑块 ​

csharp
var slider = new Panel();
var thumb = new Panel();
thumb.Parent = slider;

float sliderValue = 0;
thumb.TrackPointer(e =>
{
    if (e.HasPosition)
    {
        float ratio = Math.Clamp(e.X / slider.Width, 0f, 1f);
        sliderValue = ratio;
        thumb.Margin = new Thickness(ratio * (slider.Width - thumb.Width), 0, 0, 0);
    }
});

与 Canvas 的关系 ​

Canvas 控件没有 OnPointerMoved 事件。要在 Canvas 上跟踪指针移动,使用 DeviceInfo.PrimaryInputManager.OnPointerButtonMove,或在 Canvas 上层叠一个透明控件并使用 TrackPointer。

相关文档 ​