0

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

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

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

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

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

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

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

编辑 - 有关事件序列的更多详细信息:

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

  1. MouseDown开按钮
  2. MouseDownon 按钮(拖动处理程序)
  3. 我将此转发给按钮的父级
  4. MouseDown在父级(拖动处理程序)
  5. 鼠标被父级捕获(拖动处理程序)
  6. MouseUp在父母身上
  7. 结束拖动(拖动处理程序)

我从来没有MouseUp在按钮上看到任何事件。

4

1 回答 1

-1

我不知道Control您使用的是哪种容器,因为我已经使用 a 进行了测试,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);
      }
   }
}
于 2013-06-19T11:28:50.850 回答