我有复杂的UserControl(网格,网格的编辑控件等等),我想要处理CTRL + C键盘快捷键,但我不想通过编辑控件(文本框,组合框等)禁用本机功能。 ..)。如果CTRL + C没有被其他内部控件处理,我想自己处理它(从网格中复制整行等)。
我尝试在UserControl中覆盖WndProc方法并检查WM_COPY和WM_COPYDATA,但它不起作用。它仅适用于最终目标控件(例如TextBox)。
答案 0 :(得分:5)
您可以通过重写ProcessCmdKey()来完成此操作。检查文本框是否具有焦点。例如:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
if (keyData == (Keys.Control | Keys.C)) {
var box = this.ActiveControl as TextBoxBase;
if (box == null) {
// Do your stuff
MessageBox.Show("Copy!");
return true;
}
}
return base.ProcessCmdKey(ref msg, keyData);
}
答案 1 :(得分:0)
我没有尝试过,我认为它很重视取决于你的UserControl中的所有子控件。但通常会对具有焦点的实际控件进行击键。如果它没有处理那个击键(设置e.Handled = true
),它将会冒泡到它的父级,如果它没有处理它,它会更进一步,直到它到达形式,最后是边缘。
因此,如果您的子控件已正确编写且无法处理给定的击键(例如 Control + C ),则应该很容易将处理程序添加到您的UserControl到KeyDown
事件并做任何你喜欢的事情。
在阅读你的评论之后,我仍然认为恩里科和我所表现的方式应该是正确的。所以我认为问题在于,如果你的第三方控件之一有焦点,它无法处理复制快捷方式,但它设置e.Handled = true
导致没有关于快捷方式的父控件的进一步信息。 / p>
首先,您应该联系您的控制供应商并向他发送有关此错误行为的错误报告。
替代方案存在另一种 hacky 方式:
在表单中,您可以将KeyPreview
设置为true并拦截传入密钥。现在,您可以检查ActiveControl
内是否正确处理快捷方式(可能是对Dictionary<Type, bool>
或HashSet<Type> lackingControls
进行检查),只需保留该功能或执行任何操作并进行设置<{1}}自己。
一个小片段来说明我的意思:
e.Handled = true
此功能的缺点是,它必须放在您的表单中,而不是放入您自己编写的UserControl中。但是,当TextBox具有焦点并且在其中按下 Control + C 时,您将收到通知。
答案 2 :(得分:0)
您正在寻找的是一种将子控件引发到其容器的冒泡事件的方法,以便您可以在用户控件级别处理这些事件。
跨控件层次结构的事件自动传播内置于WPF 中,称为 Routed Events 。但是,Windows窗体中无法使用此功能,因此您必须实现自己的解决方案。
看看this SO question以获得灵感。
相关资源: