C#/ WPF - 每帧调用方法

时间:2018-01-31 22:53:13

标签: c# wpf drag-and-drop

TL; DR:我想每帧调用一个方法。

我正在两个对象之间创建一个连接(由曲线表示)。

Drag a line between two objects. 红色轮廓的矩形是我的针脚。他们可以判断拖动操作何时开始和结束。不幸的是,当光标移到外面时,它们无法接收 PreviewMouseMove 事件。但我希望能够在拖动时更新连接端点。

MyPin.cs:

private void MyPin_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    if (e.RightButton == MouseButtonState.Pressed)
        return;
    Connection.isDragging = true;
    e.Handled = true;
}

private void MyPin_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
    if (isDragging)
    {
        Connection.isDragging = false;
        e.Handled = true;
    }
}

因此,我通过使用Canvas的 PreviewMouseMove 事件来解决这个问题。

MyCanvas.cs

    private void Canvas_PreviewMouseMove(object sender, MouseEventArgs e)
    {
        if (DraggableElement.isDragging)
        {
            return;
        }
        else if(Connection.isDragging)
        {
            Connection.Preview.DragToMouse();
            e.Handled = true;
        }
        // a bunch of other else if...
    }

然而,随着项目规模的扩大,这些变通办法变得难以维护。我确实有一个更好的解决方案,但我不知道如何实现它。我想在 MyPin.cs 类中创建更新函数:

private void MyPin_Tick()
{
    // Called every frame, do drag logic here.
}

但是我如何才能在每一帧中调用此方法?

1 个答案:

答案 0 :(得分:2)

您需要做的就是使用Mouse.Capture捕获鼠标。一旦控件捕获鼠标,即使鼠标退出控件,它也将继续接收鼠标事件。

private void MyPin_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    if (e.RightButton == MouseButtonState.Pressed)
        return;
    Connection.isDragging = true;
    e.Handled = true;
    Mouse.Capture((IInputElement)sender);
}

private void MyPin_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
    if (isDragging)
    {
        Connection.isDragging = false;
        e.Handled = true;
        Mouse.Capture(null);
    }
}