为什么我的自定义控件没有接收拖/放事件?

发布于 2024-07-17 09:37:18 字数 947 浏览 6 评论 0原文

我用 C++/CLI 编写了一个自定义控件(Forms.Control 的直接子级),它将把大部分处理和所有绘制卸载到一个单独的传统 MFC 控件中。 我将此控件包装在 C# 应用程序中。 我需要能够将项目从应用程序中同一窗体上的 UserControl 拖到 C++/CLI 控件上。

由于某种原因,尽管我将AllowDrop 设置为true,但我的自定义控件没有接收任何拖/放事件。 (我已经验证了AllowDrop在运行时为true。)我从未有机会检查/操作DragEventArgs,因为从未调用回调。

我已经验证拖放功能正常。 例如,如果我用面板替换自定义控件,我就能很好地获得拖放回调。

是否必须在控件中实现一些额外的内容才能支持拖放回调? 系统是否必须处理一些微妙的问题才能识别出某个控件正在悬停并且应该成为拖放操作的目标?

注意:

用于绘画的 MFC 控件尚不可用,因此我只是绘画一个我正在尝试的简单渐变背景(通过 OnPaintBackground)画到。 我还在 OnPaint 中绘制了一个较小的渐变矩形。

我尝试在创建自定义控件的句柄之前(通过设计器/构造函数代码)和创建句柄之后(通过 OnHandleCreated 覆盖)设置AllowDrop = true。 行为上没有区别。

自定义控件上的拖动光标永远不会从默认的“不可拖动”光标发生变化。

我从 UserControl 子控件上的 MouseDown 事件的事件处理程序中调用 this.DoDragDrop()

DragDrop 似乎可以与我在 C# 中创建的另一个自定义控件(在与用户控件相同的程序集中)一起使用。 它可以很好地捕获回调。 只有我的 C++/CLI 控件看不到它们。 初始化组件 goo 是无关紧要的。 我可以将其全部注释掉,无需任何更改。

I've written a custom control (an immediate child of Forms.Control) in C++/CLI that will offload most of its processing and all of its painting to a separate legacy-ish MFC control. I'm wrapping this control in a C# application. I need to be able to drag items onto the C++/CLI control from a UserControl on the same form in the application.

For some reason, my custom control isn't receiving any of the drag/drop events in spite of my setting AllowDrop to true. (I've verified that AllowDrop is true at runtime.) I never get an opportunity to examine/manipulate the DragEventArgs because the callbacks are never called.

I've verified that drag and drop otherwise functions normally. If I replace the custom control with a Panel, for example, I get the dragdrop callbacks just fine.

Is there something additional that must be implemented in a Control to support dragdrop callbacks? Is there something subtle that must be dealt with for the system to recognize that a control is being hovered over and should be the target of a dragdrop operation?

Notes:

The MFC control that will do the painting is not yet available to me, so I'm just painting a simple gradient background (via OnPaintBackground) that I'm trying to paint to. I'm also painting a smaller gradient rectangle in OnPaint.

I have tried setting AllowDrop = true both before the custom control's handle is created (via designer/constructor code) and after the handle is created (via OnHandleCreated override). No difference in behavior.

The drag cursor never changes from the default "no drag available" cursor over the custom control.

I'm calling this.DoDragDrop() from an event handler for a MouseDown event on a subcontrol of the UserControl.

DragDrop seems to work ok with another custom control I created in C# in the same assembly as the user control. It captures the callbacks just fine. Only my C++/CLI control isn't seeing them. The initializecomponent goo is irrelevant. I can comment it all out with no change.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

晨曦慕雪 2024-07-24 09:37:18

我发现了我的错误,所以我会在这里回答,以防其他人犯类似的错误。 看起来我确实在我的问题中暗示了答案,尽管我当时没有意识到。

在我的问题中,我指出

我尝试设置AllowDrop = true
两者都在自定义控件之前
创建句柄(通过
设计者/构造者代码)及之后
创建句柄(通过
OnHandleCreated 覆盖)。 不
行为上的差异。

这实际上就是崩溃发生的地方。 我未能阅读 OnHandleCreated 文档明确指出我需要记住调用 OnHandleCreated 的基类实现。

Reflector 显示 Control::OnHandleCreated 负责设置 Control 的内部事件通知结构。 我从未调用过 Control::OnHandleCreated,因此内部事件通知结构从未正确构建。 该事件结构(反射器再次显示)负责触发 OnDragOver 等,因此缺少事件结构导致我丢失事件。

答案:

当你重写它时,一定要调用OnHandleCreated的基类实现!

I figured out my mistake, so I'll answer it here in case someone else makes a similar mistake. It looks like I did hint at the answer in my question, though I didn't realize it at the time.

In my question, I stated that

I have tried setting AllowDrop = true
both before the custom control's
handle is created (via
designer/constructor code) and after
the handle is created (via
OnHandleCreated override). No
difference in behavior.

This is actually where the breakdown occurred. I failed to read the OnHandleCreated documentation that specifically states I needed to remember to call the base class' implementation of OnHandleCreated.

Reflector shows that Control::OnHandleCreated is responsible for setting up Control's internal event notification structure. I never called Control::OnHandleCreated, so the internal event notification structure was never getting properly built up. This eventing structure (reflector again shows) is responsible for firing OnDragOver, etc, so the missing eventing structure resulted in my missing events.

Answer:

Be sure that you call the base class implementation of OnHandleCreated when you override it!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文