基本上我想要做的是将自定义窗口的状态从最大化更改为正常状态,并调整窗口的位置,当用户单击标题栏并将鼠标移动到标题栏上时,在我的情况下,标题栏是一个简单的边框。
显而易见的事情是将事件处理程序附加到MouseMove
并检查鼠标左键是否被按下:
private void OnMouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
Console.WriteLine("Mouse moved" + Mouse.Captured);
}
}
问题是MouseMove
当鼠标捕获发生变化时发生。所以在我的应用程序中,窗口将捕捉到Normal
打开弹出窗口并单击边框后的状态,捕捉应该在开始拖动后发生。
下面是上述代码的 XAML 来证明问题:
<Grid MouseMove="OnMouseMove" Background="AliceBlue">
<ComboBox Height="23">
<ComboBoxItem>Test1</ComboBoxItem>
<ComboBoxItem>Test1</ComboBoxItem>
<ComboBoxItem>Test1</ComboBoxItem>
<ComboBoxItem>Test1</ComboBoxItem>
<ComboBoxItem>Test1</ComboBoxItem>
<ComboBoxItem>Test1</ComboBoxItem>
</ComboBox>
</Grid>
问题步骤,在debug中运行上面的代码:
- 点击
ComboBox
打开其弹出窗口。
- 单击蓝色网格(这将关闭弹出窗口)。
Notice:输出窗口显示消息“鼠标已移动”
预期行为:由于只进行了单击(没有鼠标移动),我不想要MouseMove
event.
据我了解,MouseMove
被解雇时Mouse.Captured
元素发生变化,这是正常的,但我需要一种方法来区分正常的MouseMove
and a MouseMove
由鼠标捕获引起。
EDIT:
有关此问题的更复杂的示例可以在 MahApps.Metro 演示中找到。步骤与上述相同 - 当窗口处于最大化状态时,打开一个弹出窗口并单击标题栏。您会注意到窗口从最大化状态突然变为正常状态。这不应该发生,因为您没有双击或拖动标题栏。
到目前为止我的解决方案:
因为我知道这是由鼠标捕获的元素更改引起的,所以我处理了LostMouseCapture
事件并保存鼠标位置:
private Point mousePositionAfterCapture;
private void OnLostMouseCapture(object sender, MouseEventArgs e)
{
mousePositionAfterCapture = e.GetPosition(this);
}
And in MouseMove
处理程序我检查上次丢失鼠标捕获后位置是否已更改:
private void OnMouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
Point currentPossition = e.GetPosition(this);
if (currentPossition == mousePositionAfterCapture)
//means that the MouseMove event occurred as a result of
//Mouse Captured element change, we wait until an actual
//mouse move will occure
return;
Console.WriteLine("Mouse moved" + Mouse.Captured);
}
}