在 UserControl 上处理剪贴板副本
我有复杂的用户控件(网格、网格编辑控件等...)并且我想要处理 CTRL+C 键盘快捷键,但是我不想通过编辑控件(文本框、组合框等...)禁用本机功能。如果 CTRL+C 不由其他内部控件处理,我想自己处理它(从网格复制整行等...)。
我尝试覆盖 UserControl 中的 WndProc 方法并检查 WM_COPY 和 WM_COPYDATA,但它不起作用。它仅适用于最终目标控件(例如 TextBox)。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以通过重写 ProcessCmdKey() 来完成此操作。检查文本框是否具有焦点。例如:
You can do this by overriding ProcessCmdKey(). Check if a text box has the focus. For example:
您正在寻找一种将子控件引发的事件冒泡的方法,直到其容器,以便您可以在用户控件级别处理这些事件。
跨控件层次结构的事件自动传播内置于 WPF 中,称为路由事件。但是,此功能在 Windows 窗体中并不是开箱即用的,因此您必须实现自己的解决方案。
看看这个问题以获得一些灵感。
相关资源:
What you are looking for is a way to bubble events raised by a child control up to its container so that you can handle those events at the User Control's level.
The automatic propagation of events across the control hierarchy is built into WPF and is called Routed Events. However this functionality is not available out of the box in Windows Forms, so you will have to implement your own solution.
Have a look at this SO question to get some inspiration.
Related resources:
我没有尝试过,我认为这很大程度上取决于用户控件内的所有子控件。但通常情况下,击键是针对具有焦点的实际控件。如果它不处理该击键(设置
e.Handled = true
),它将向上冒泡到其父级,如果不处理它,它将进一步前进,直到到达表单最后是角膜缘。因此,如果您的子控件编写正确并且它们无法处理给定的击键(例如 Control + C),则应该很容易将处理程序添加到您的 UserControl 中
KeyDown
活动并做任何你喜欢的事情。更新
阅读您的评论后,我仍然认为恩里科和我所展示的方式应该是正确的。所以我认为问题是,如果您的第 3 方控件之一具有焦点,它无法处理复制快捷方式,但它设置了
e.Handled = true
导致没有进一步的信息有关快捷方式的父控件。因此,首先您应该联系您的控件供应商并向他发送有关此错误行为的错误报告。
另外还有另一种hacky方式:
在表单中,您可以设置
KeyPreview
设置为 true 并拦截传入的按键。现在您可以检查是否在ActiveControl
是正确处理快捷方式的东西(可能是针对Dictionary
或HashSetmissingControls
进行检查)只需保留该功能或执行任何您想要的操作并自行设置e.Handled = true
即可。更新 2
一个小片段来说明我的意思:
此功能的缺点是,它必须放入您的表单中,而不是放入您自己编写的 UserControl 中。但是这样,当 TextBox 获得焦点并且 Control + C 被按下时,您会收到通知。
I didn't try it out and i think it heavy depends on all the child controls, which are within your UserControl. But normally a keystroke is given to the actual control that has the focus. If it doesn't handle that keystroke (setting
e.Handled = true
), it would be bubble up to its parent and if that doesn't handle it, it would go further till it reaches the form and finally the limbus.So if your child controls are properly written and they can't handle the given keystroke (e.g. Control + C) it should be easy to add a handler into your UserControl to the
KeyDown
event and do whatever you like.Update
After reading your comments, i still think that the way shown by Enrico and me should be the correct one. So i think the problem is that if one of your 3rd party controls has the focus it is not able to handle the copy shortcut, but it sets the
e.Handled = true
leading to no further informations of the parent controls about the shortcut.So at first you should contact your control vendor and send him a bug report about this wrong behaviour.
Alternative there exists another hacky way:
In your form you can set the
KeyPreview
to true and intercept the incoming key. Now you could check if within theActiveControl
is something that handles the shortcut correctly (maybe a check against aDictionary<Type, bool>
or aHashSet<Type> lackingControls
) and just leave the function or do whatever you want and setting thee.Handled = true
by yourself.Update 2
A little snippet to illustrate what i meant:
The drawback of this functionality is, that it must be placed into your form, not into your self-written UserControl. But that way you will be informed, when a TextBox has the focus and Control + C is pressed within.