Wpf 如果另一个对象有mousecapture,如何为一个对象启动MouseEnter?
我有一个奇怪的问题和一个vb.NET2010和wpf4项目。我有一个标签,当点击时,它会捕获鼠标(MyLabel.captureMouse),并沿着它在屏幕上移动,直到鼠标再次点击,此时对象和鼠标夹被释放 但是,对于另一个对象,我仍然需要mouseenter的功能。我如何让这两件事一起工作 编辑:似乎有两种解决方案,其中一种是我发现的。然而,由于Rick的也应该有效(尽管由于我的截止日期而未经测试),而且我讨厌在这里回答我自己的问题,所以我接受了他的回答Wpf 如果另一个对象有mousecapture,如何为一个对象启动MouseEnter?,wpf,vb.net,mouse,Wpf,Vb.net,Mouse,我有一个奇怪的问题和一个vb.NET2010和wpf4项目。我有一个标签,当点击时,它会捕获鼠标(MyLabel.captureMouse),并沿着它在屏幕上移动,直到鼠标再次点击,此时对象和鼠标夹被释放 但是,对于另一个对象,我仍然需要mouseenter的功能。我如何让这两件事一起工作 编辑:似乎有两种解决方案,其中一种是我发现的。然而,由于Rick的也应该有效(尽管由于我的截止日期而未经测试),而且我讨厌在这里回答我自己的问题,所以我接受了他的回答 在等待他对我遇到的问题做出回应的过程中,
在等待他对我遇到的问题做出回应的过程中,我最终找到了自己的解决方案。因此,请务必阅读我的答案和Rick的答案。在我的经验中,使用捕获不是处理拖放(如果您正在实现拖放)的方法,这正是因为您在此处陈述的原因 我通过跟踪鼠标按钮和移动并沿方向平移控件来解决这种情况
也可以使用。如果另一个对象是您的一个对象,则您的标签和另一个对象可以在使用合成事件捕获鼠标时进行协作。例如,在鼠标移动处理程序中,您可以检查
mouse.DirectlyOver
以查看它是否是另一个对象,如果是,请做一些簿记,然后在另一个对象上使用MouseEnter
或MouseLeave
调用RaiseEvent
。如果你有一堆这样的东西,那么你就有更多的簿记工作要做
编辑:
上面提到的是鼠标.DirectlyOver
,它在捕获鼠标时不起作用。为了使上述内容更加具体,并修复该错误,下面是一个完整的工作示例
以下是显示画布、具有鼠标捕获处理的矩形和具有enter/leave处理的椭圆的标记:
<Grid>
<Canvas>
<Rectangle Canvas.Left="0" Canvas.Top="0"
Fill="Red" Width="100" Height="100"
MouseLeftButtonDown="Rectangle_MouseLeftButtonDown"
MouseMove="Rectangle_MouseMove"
MouseLeftButtonUp="Rectangle_MouseLeftButtonUp"/>
<Ellipse Canvas.Left="0" Canvas.Top="100"
Fill="Green" Width="100" Height="100"
MouseEnter="Ellipse_MouseEnter"
MouseLeave="Ellipse_MouseLeave">
<Ellipse.RenderTransform>
<ScaleTransform/>
</Ellipse.RenderTransform>
</Ellipse>
</Canvas>
</Grid>
如果在调试器下运行演示,无论是否捕获鼠标,都会调用enter/leave处理程序。因为我用来模拟对象“拖动”的代码涉及到获取鼠标位置,我抓住这个机会,写了一段代码,检查鼠标在画布上的位置是否在我需要mouseenter/mouseleave的每个对象的边界内。这一点尤其有效,因为我需要的对象mouseover/mouseleave用于从未改变的位置 这是我最终代码的精简版本
'Declare the left, right, top, and bottom boundaries of each of the "drop-spot" objects in relation to the canvas. This could also be determined programamtically for objects that change position.
Private Tile1PosL As Double = 55
Private Tile1PosT As Double = 30
Private Tile2PosL As Double = 164
Private Tile2PosT As Double = 69
Private Tile3PosL As Double = 282
Private Tile3PosT As Double = 41
Private Tile4PosL As Double = 405
Private Tile4PosT As Double = 69
Private Tile5PosL As Double = 514
Private Tile5PosT As Double = 12
Private Sub Tile1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Input.MouseEventArgs) Handles Tile1.MouseMove
If IsDragging1 = True Then
'My dragging functions go here.
'Get the mouse position on the canvas (canv).
Dim MousePosX As Double = e.GetPosition(canv).X
Dim MousePosY As Double = e.GetPosition(canv).Y
'Check to see if the mouse is within the boundaries of any of the "drop-spot" objects (Hole1, Hole2, Hole3, Hole4, Hole5).
If MousePosX > Hole1L And MousePosX < Hole1R And MousePosY > Hole1T And MousePosY < Hole1B Then
'Call the subroutine containing the code that would ordinarily go in "mouseenter".
Hole1_TileEnter()
ElseIf MousePosX > Hole2L And MousePosX < Hole2R And MousePosY > Hole2T And MousePosY < Hole2B Then
'Call the subroutine containing the code that would ordinarily go in "mouseenter".
Hole2_TileEnter()
ElseIf MousePosX > Hole3L And MousePosX < Hole3R And MousePosY > Hole3T And MousePosY < Hole3B Then
'Call the subroutine containing the code that would ordinarily go in "mouseenter".
Hole3_TileEnter()
ElseIf MousePosX > Hole4L And MousePosX < Hole4R And MousePosY > Hole4T And MousePosY < Hole4B Then
'Call the subroutine containing the code that would ordinarily go in "mouseenter".
Hole4_TileEnter()
ElseIf MousePosX > Hole5L And MousePosX < Hole5R And MousePosY > Hole5T And MousePosY < Hole5B Then
'Call the subroutine containing the code that would ordinarily go in "mouseenter".
Hole5_TileEnter()
Else
'If the mouse is not within any of the "drop-spot" objects, call the subroutine containing the code that would ordinarily go in each object's "mouseleave". NOTE: This code contains statements that determine that the mouse had been inside one of the "drop-spots" before actually triggering the rest of its code.
Hole_TileLeave()
End If
End If
End If
'This subroutine, with minor modifications, works for my Tile2, Tile3, Tile4, and Tile5 as well.
End Sub
'声明每个“放置点”对象相对于画布的左、右、上和下边界。对于改变位置的对象,这也可以通过编程来确定。
专用瓷砖1位置为双=55
私人瓷砖1双柱=30
专用Tile2PosL作为双精度=164
私人瓷砖2双柱=69
专用Tile3PosL为双精度=282
专用瓷砖3双柱=41
专用Tile4PosL为双精度=405
私人贴片作为双贴片=69
专用瓷砖5POSL双精度=514
私人贴片作为双贴片=12
私有子tile1u MouseMove(ByVal sender作为对象,ByVal e作为System.Windows.Input.MouseEventArgs)处理Tile1.MouseMove
如果IsDraging1=True,则
“我的拖动功能在这里。
'获取画布上的鼠标位置(canv)。
将鼠标点设为双精度=e.GetPosition(canv).X
将鼠标位置调暗为Double=e.GetPosition(canv).Y
'检查鼠标是否位于任何“放置点”对象(孔1、孔2、孔3、孔4、孔5)的边界内。
如果MousePosX>Hole1L和MousePosXHole1T和MousePosYHole2L和MousePosXHole2T和MousePosYHole3L和MousePosXHole3T和MousePosYHole4L和MousePosXHole4T和MousePosYHole5L和MousePosXHole5T和MousePosY
这不是拖放操作。这只是在图形层面上看起来,但我已经排除了拖放作为一种可行的选择。我不太明白…你能不能换一点说法?您所说的“…您可以直接检查Mouse.DirectlyOver以查看它是否是另一个对象…”是什么意思?如果另一个对象捕获了鼠标,该功能还会起作用吗?当然,mouse.DirectlyOver是被捕获鼠标最好的朋友。您只需调用它,看看它返回的是否是您要查找的类;我完全错了。Mouse.DirectlyOver不支持
'Declare the left, right, top, and bottom boundaries of each of the "drop-spot" objects in relation to the canvas. This could also be determined programamtically for objects that change position.
Private Tile1PosL As Double = 55
Private Tile1PosT As Double = 30
Private Tile2PosL As Double = 164
Private Tile2PosT As Double = 69
Private Tile3PosL As Double = 282
Private Tile3PosT As Double = 41
Private Tile4PosL As Double = 405
Private Tile4PosT As Double = 69
Private Tile5PosL As Double = 514
Private Tile5PosT As Double = 12
Private Sub Tile1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Input.MouseEventArgs) Handles Tile1.MouseMove
If IsDragging1 = True Then
'My dragging functions go here.
'Get the mouse position on the canvas (canv).
Dim MousePosX As Double = e.GetPosition(canv).X
Dim MousePosY As Double = e.GetPosition(canv).Y
'Check to see if the mouse is within the boundaries of any of the "drop-spot" objects (Hole1, Hole2, Hole3, Hole4, Hole5).
If MousePosX > Hole1L And MousePosX < Hole1R And MousePosY > Hole1T And MousePosY < Hole1B Then
'Call the subroutine containing the code that would ordinarily go in "mouseenter".
Hole1_TileEnter()
ElseIf MousePosX > Hole2L And MousePosX < Hole2R And MousePosY > Hole2T And MousePosY < Hole2B Then
'Call the subroutine containing the code that would ordinarily go in "mouseenter".
Hole2_TileEnter()
ElseIf MousePosX > Hole3L And MousePosX < Hole3R And MousePosY > Hole3T And MousePosY < Hole3B Then
'Call the subroutine containing the code that would ordinarily go in "mouseenter".
Hole3_TileEnter()
ElseIf MousePosX > Hole4L And MousePosX < Hole4R And MousePosY > Hole4T And MousePosY < Hole4B Then
'Call the subroutine containing the code that would ordinarily go in "mouseenter".
Hole4_TileEnter()
ElseIf MousePosX > Hole5L And MousePosX < Hole5R And MousePosY > Hole5T And MousePosY < Hole5B Then
'Call the subroutine containing the code that would ordinarily go in "mouseenter".
Hole5_TileEnter()
Else
'If the mouse is not within any of the "drop-spot" objects, call the subroutine containing the code that would ordinarily go in each object's "mouseleave". NOTE: This code contains statements that determine that the mouse had been inside one of the "drop-spots" before actually triggering the rest of its code.
Hole_TileLeave()
End If
End If
End If
'This subroutine, with minor modifications, works for my Tile2, Tile3, Tile4, and Tile5 as well.
End Sub