我基本上是在写一个简单的浮动面板,可以通过拖动它的标题栏(这是一个网格本身)来改变它的位置。但我无法让它发挥作用!似乎MouseEventArgs.GetPosition
返回错误的观点。我在这里错过了什么?
public class FloatingPanel : Grid
{
Grid gridTitle;
bool dragging = false;
Point lastPos;
public FloatingPanel(UserControl gadget)
{
this.MouseMove += FloatingPanel_MouseMove;
gridTitle = new Grid();
gridTitle.Height = 25;
gridTitle.VerticalAlignment = System.Windows.VerticalAlignment.Top;
gridTitle.Background = Brushes.Cyan;
gridTitle.MouseLeftButtonDown += gridTitle_MouseLeftButtonDown;
gridTitle.MouseLeftButtonUp += gridTitle_MouseLeftButtonUp;
this.Children.Add(gridTitle);
this.Height = gadget.Height + 25;
this.Width = gadget.Width;
gadget.VerticalAlignment = System.Windows.VerticalAlignment.Bottom;
this.Children.Add(gadget);
}
void gridTitle_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
dragging = false;
}
void gridTitle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
lastPos = Mouse.GetPosition(this);
dragging = true;
}
void FloatingPanel_MouseMove(object sender, MouseEventArgs e)
{
if(dragging)
{
Vector delta = e.GetPosition(this) - lastPos;
this.Margin = new Thickness(this.Margin.Left + delta.X, this.Margin.Top + delta.Y, this.Margin.Right, this.Margin.Bottom);
lastPos = e.GetPosition(this);
}
}
}
我也尝试使用System.Windows.Forms.Cursor.Position
和System.Windows.Forms.Control.MousePosition
来显示屏幕上的位置。但没有运气。
解决方案:问题通过3次修改解决(如Sphinxxx指出):
- 使用MouseEventArgs.GetPosition(null)
代替MouseEventArgs.GetPosition(this)
- 使用mousedown
和mouseup
在Mouse.Capture(gridTitle)
和Mouse.Capture(null)
个事件中捕获和释放鼠标
- 设置网格的水平和垂直对齐方式。 (这对我来说似乎很奇怪。为什么点头设置对齐会导致问题?)
答案 0 :(得分:2)
在_MouseMove
中,您尝试使用e.GetPosition(this)
计算移动,但只能获得相对于Grid
的鼠标指针位置。您需要找到相对于其他UI元素的位置,例如包含Window
以便知道网格应移动多少。
在e.GetPosition(null)
和_MouseLeftButtonDown
中尝试_MouseMove
( null 而不是此)来计算正确{{1 }}第
本文阐述了不同之处: Getting the Mouse Position Relative to a Specific Element
编辑:更强大delta
:
在构造函数中,避免使用最终位于标题栏顶部的小工具,方法是将它们放在两个单独的FloatingPanel
中(并让WPF句柄宽度和高度):
RowDefinition
在public FloatingPanel(FrameworkElement gadget)
{
gridTitle = new Grid();
gridTitle.Height = 25;
gridTitle.Background = Brushes.Cyan;
gridTitle.MouseLeftButtonDown += gridTitle_MouseLeftButtonDown;
gridTitle.MouseMove += gridTitle_MouseMove;
gridTitle.MouseLeftButtonUp += gridTitle_MouseLeftButtonUp;
//Create two grid rows - one to hold the title bar..
this.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto });
Grid.SetRow(gridTitle, 0);
this.Children.Add(gridTitle);
//..and one two hold the gadget:
this.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto });
Grid.SetRow(gadget, 1);
this.Children.Add(gadget);
}
/ ..ButtonDown
处理程序中,使标题栏“捕获”(并释放)鼠标移动,以便鼠标指针在移动速度过快时不会“滑落”:
..ButtonUp
编辑2:没有void gridTitle_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
//Relese a previous capture:
Mouse.Capture(null);
dragging = false;
}
void gridTitle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
lastPos = Mouse.GetPosition(null);
//Capture the mouse to ensure we get all future mouse movements:
Mouse.Capture(gridTitle);
dragging = true;
}
的替代方案:
Mouse.Capture()