如何从子用户控件向父级传递消息

4
这是一个Windows Forms / .Net C#问题。我有一个没有边框的窗口,其透明键和背景颜色使其完全透明。 在窗口内是一些用户控件。我想移动这个窗口。我知道如何在父窗口上做到这一点,但我的问题是子控件是唯一可见且可单击的内容。问题是:如何将某些消息传递给父级,以便当鼠标右键按下并在任何一个子控件上移动时,父级可以移动?或者你可以建议另一种方法吗?谢谢帮助。- Mark

1
在窗口上添加一些东西,让用户明显地知道她可以点击并移动窗口。除了带有“单击此处移动”标签的靶心外,标题栏也是一个明显的UI小工具。 - Hans Passant
4个回答

7
我认为最简单的方法是将此事件添加到您的子控件中:
/// <summary>
/// The event that you will throw when the mouse hover the control while being clicked 
/// </summary>
public event EventHandler MouseRightClickedAndHoverChildControl;

接下来,所有家长需要做的就是订阅这些事件并进行操作,以移动家长:

ChildControl.MouseRightClickedAndHoverChildControl += OnMouseHoverChildControl;

private void OnMouseHoverChildControl(object sender, EventArgs e)
{
    //do foo...
}

7
即使不使用 SendMessage,您也可以使用 System.Windows.Forms.Message 类来实现目标。如果您已经完成了拖动操作,那么我猜您应该熟悉 WM_NCLBUTTONDOWN 消息。在控件的 MouseDown 事件中向父级发送此消息。
以下是一个示例,用于通过单击控件 label1 移动窗体。请注意第一行,其中使用 sender 释放了从单击控件中捕获的内容。这样,您可以将此处理程序设置为所有旨在移动窗体的控件。
这是完整的移动窗体的代码。不需要其他任何东西。
希望这有所帮助。

谢谢您的建议。不幸的是,您提供的代码导致用户控件在父窗体的边界内移动。这是一种很有趣的效果,但不幸的是不符合我的要求。 - Mark Wager-Smith
刚刚发现,将代码中的Handle更改为parent.Handle后...它运行得非常好。非常感谢您的帮助。现在我只需要弄清楚如何允许UserControl处理一些自己的鼠标事件,并仅将拖动事件传递给父级。但我觉得我已经很接近了。再次感谢。 - Mark Wager-Smith
嗨,马克,欢迎你。如果你觉得我的回答有用,请将其标记为有用或接受的答案,谢谢。 你想通过你的用户控件处理哪些事件? - Petr Havlicek
1
太棒了,我以为我要在所有控件的WndProc上进行重写。非常感谢。 - string.Empty
我同意,纯天才! - Sabuncu

0
我确切地有这个问题... 但得到了不同的答案。 如果您在WndProc中有消息,只需将句柄更改为父级的句柄,然后将其传递即可。
我需要在我们派生的TextBox中执行此操作...即使将其滚动条设置为None,TextBox也会吃掉滚轮事件。 我希望这些事件向上传播到窗体。 所以,我只需将以下内容放入我的派生TextBox的WndProc中:
            case 0x020A: // WM_MOUSEWHEEL
            case 0x020E: // WM_MOUSEHWHEEL
                if (this.ScrollBars == ScrollBars.None && this.Parent != null)
                    m.HWnd = this.Parent.Handle; // forward this to your parent
                base.WndProc(ref m);
                break;

            default:
                base.WndProc(ref m);
                break;

0

我应该在我的WndProc中捕获哪些消息?我是否只需将它们原样传递给parent.Handle(相同的wParam和lParam)? - Mark Wager-Smith
你应该捕获链接中的所有鼠标消息。你需要调整坐标相对于父控件。(调用PointToScreen,然后PointToScreen - SLaks
1
谢谢。我想我懂了。但是你说PointToScreen然后再PointToScreen?你是说使用PointToScreen获取屏幕坐标,然后使用PointToClient将其转换为父窗口的客户端坐标吗? - Mark Wager-Smith
是的,我确实是那个意思。(笔误) - SLaks

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接