我正在尝试在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;
}
首先点击进入按钮将他移开很远然后我可以移动按钮,但这是第一次将按钮移开。我缺少什么?
答案 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();
}
}