WPF使用鼠标移动元素

时间:2017-09-23 14:32:25

标签: c# wpf

我正在尝试在WPF应用程序中使用鼠标移动按钮。

XAML Grid是结构的根:

<Grid Name="MyGrid"            >
    <Button Name="Samplebutton"
            PreviewMouseDown="Samplebutton_PreviewMouseDown"
            PreviewMouseUp="Samplebutton_PreviewMouseUp"
            PreviewMouseMove="Samplebutton_PreviewMouseMove"
            Content="Moving" Width="100" Height="35"/>
</Grid>

代码背后:

private bool _isMoving;


private void Samplebutton_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    _isMoving = true;
}

private void Samplebutton_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
    _isMoving = false;
}

private void Samplebutton_PreviewMouseMove(object sender, MouseEventArgs e)
{
    if (!_isMoving) return;

    TranslateTransform transform = new TranslateTransform();
    transform.X = Mouse.GetPosition(MyGrid).X;
    transform.Y = Mouse.GetPosition(MyGrid).Y;
    this.Samplebutton.RenderTransform = transform;
}

首先点击进入按钮将他移开很远然后我可以移动按钮,但这是第一次将按钮移开。我缺少什么?

4 个答案:

答案 0 :(得分:4)

以下是您问题的完整解决方案:

private bool _isMoving;
private Point? _buttonPosition;
private double deltaX;
private double deltaY;
private TranslateTransform _currentTT;

private void Samplebutton_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    if(_buttonPosition == null)
        _buttonPosition = Samplebutton.TransformToAncestor(MyGrid).Transform(new Point(0, 0));
    var mousePosition = Mouse.GetPosition(MyGrid);
    deltaX = mousePosition.X - _buttonPosition.Value.X;
    deltaY = mousePosition.Y - _buttonPosition.Value.Y;
    _isMoving = true;
}

private void Samplebutton_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
    _currentTT = Samplebutton.RenderTransform as TranslateTransform;
    _isMoving = false;
}

private void Samplebutton_PreviewMouseMove(object sender, MouseEventArgs e)
{
    if (!_isMoving) return;

    var mousePoint = Mouse.GetPosition(MyGrid);

    var offsetX = (_currentTT == null ?_buttonPosition.Value.X : _buttonPosition.Value.X - _currentTT.X) + deltaX - mousePoint.X;
    var offsetY = (_currentTT == null ? _buttonPosition.Value.Y : _buttonPosition.Value.Y - _currentTT.Y) + deltaY - mousePoint.Y;

    this.Samplebutton.RenderTransform = new TranslateTransform(-offsetX, -offsetY);
}

答案 1 :(得分:2)

您需要在第一个实例中保存鼠标的位置,并始终使用&#34; relative&#34;从那时起的X / Y位置

private double _startX; // Or whatever number type Mouse.GetPosition(MyGrid).X returns
private double _startY; // Or whatever number type Mouse.GetPosition(MyGrid).Y returns   

private void Samplebutton_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    _startX = Mouse.GetPosition(MyGrid).X;
    _startY = Mouse.GetPosition(MyGrid).Y;
    _isMoving = true;
}

private void Samplebutton_PreviewMouseMove(object sender, MouseEventArgs e)
{
    if (!_isMoving) return;

    TranslateTransform transform = new TranslateTransform();
    transform.X = Mouse.GetPosition(MyGrid).X - _startX;
    transform.Y = Mouse.GetPosition(MyGrid).Y - _startY;
    this.Samplebutton.RenderTransform = transform;
}

答案 2 :(得分:1)

Samplebutton_PreviewMouseUp 我认为_isMoving = false就足够了

答案 3 :(得分:0)

这是一个古老的帖子,但是(我认为)这是一种更好的方法:

我认为您不应该使用布尔值来检查鼠标是否拖动了当前控件。此外,使用PreviewMouse....是获取鼠标位置(当鼠标不在控件上方时)的无用修补程序

您应该改用鼠标。当您捕获鼠标时,即使鼠标不在控件上方(即使在当前窗口之外),mouse_move事件仍然会引发。我认为这是应该做的方法。它更加简单易读。

这是一个例子:

public partial class VisualBlock : UserControl
{
    private Point _positionInBlock;

    public VisualBlock()
    {
        InitializeComponent();
    }

    private void UserControl_MouseDown(object sender, MouseButtonEventArgs e)
    {
        // when the mouse is down, get the position within the current control. (so the control top/left doesn't move to the mouse position)
        _positionInBlock = Mouse.GetPosition(this);

        // capture the mouse (so the mouse move events are still triggered (even when the mouse is not above the control)
        this.CaptureMouse();
    }

    private void UserControl_MouseMove(object sender, MouseEventArgs e)
    {
        // if the mouse is captured. you are moving it. (there is your 'real' boolean)
        if (this.IsMouseCaptured)
        {
            // get the parent container
            var container = VisualTreeHelper.GetParent(this) as UIElement;

            // get the position within the container
            var mousePosition = e.GetPosition(container);

            // move the usercontrol.
            this.RenderTransform = new TranslateTransform(mousePosition.X - _positionInBlock.X, mousePosition.Y - _positionInBlock.Y);
        }
    }

    private void UserControl_MouseUp(object sender, MouseButtonEventArgs e)
    {
        // release this control.
        this.ReleaseMouseCapture();
    }
}