可拖动控件内的可点击控件

时间:2013-06-19 09:46:29

标签: c# .net windows winforms

我有一个可拖动的控件(A),里面是一个按钮。 A中还有其他控件,即按钮不会填充A.

为了管理拖动功能,控件(A)捕获任何MouseDown事件。它稍后根据鼠标移动的距离决定是否开始拖动。

如果单击该按钮,然后在启动拖动之前收到MouseUp事件,我希望触发该按钮的Click事件。

目前,这不会发生,因为父控件(A)捕获了MouseUp事件。我可以在A上实现功能来手动处理:

private void MouseUp(object sender, MouseEventArgs e) {
    if (DragHasStarted) {
        DealWithDrag();
    }
    else {
        DelegateToChildControls();
    }
}

然而,这很复杂,并且不能很好地扩展,因为DelegateToChildControls需要确定要委托给哪个孩子。

有没有办法让Windows处理这个并直接调用按钮的Click方法,如果父控件没有处理MouseUp事件?

修改 - 有关事件序列的更多详细信息:

单击按钮时会看到以下事件序列:

    按钮上的
  1. MouseDown
  2. 按钮上的
  3. MouseDown(拖动处理程序)
  4. 我将此转发给按钮的父级
  5. 父项上的
  6. MouseDown(拖动处理程序)
  7. 鼠标捕获的鼠标(拖动处理程序)
  8. 父母
  9. MouseUp
  10. 结束拖动(拖动处理程序)
  11. 我从未在按钮上看到MouseUp事件。

1 个答案:

答案 0 :(得分:-1)

我不知道您使用的是哪种Control容器,因为我使用UserControl进行了测试,我可以与UserControl的所有孩子进行互动但是如果你有兴趣点击这些孩子,我有这个解决方案:

[DllImport("user32")]
private static extern IntPtr WindowFromPoint(POINT point);
[DllImport("user32")]
private static extern int SendMessage(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam);
struct POINT
{
  public int x, y;
}
private void MouseUp(object sender, MouseEventArgs e){
   if(DragHasStarted){
      DealWithDrag();
   }
   else {
      Point screenLocation = PointToScreen(e.Location);
      IntPtr childHandle = WindowFromPoint(new POINT{x=screenLocation.X,y=screenLocation.Y });
      if(childHandle != IntPtr.Zero){
         SendMessage(childHandle, 0x201, IntPtr.Zero, IntPtr.Zero);
         SendMessage(childHandle, 0x202, IntPtr.Zero, IntPtr.Zero);
      }
   }
}