在我们的应用程序的主要处理表单中,我们使用alt代码(以& Label作为标签文本,例如使用Alt-L快速导航到控件),以便在用户需要时快速导航到屏幕上跳跃摆脱传统的导航流程 - 但最近我们遇到了障碍:
我们有一个用户控件,它在窗体上处理很多,其中有一个控件,需要与用户控件之外的另一个控件共享一个alt-code(Alt-R)。通常,这不是问题,因为我们可以将它们都设置为Alt-R,而Alt-R将在两者之间切换。由于其中一个控件位于用户控件内,而一个控件不在用户控件内,因此一旦焦点位于用户控件内,它就不会在两个控件共享Alt代码的情况下切换到用户控件之外。
我是否可以设置任何属性来允许此操作而无需编写自定义逻辑来处理?自定义逻辑的主要问题是这些alt代码中的一些可以是用户定义的,当我想这应该正常工作时,必须编写一个包罗万象的处理方法并不理想。在正常的Windows窗体引擎
中答案 0 :(得分:3)
我找不到与使用P / Invoke不同的解决方案。
如果它不适合该方案,可能会有另一种简单的方法。
第一个问题:拦截一个keydown事件。在这种情况下,KeyDown事件处理程序并没有那么有用,所以你必须在""并获取WindowProc消息 第二个问题:让Container控件知道必须处理keydown事件。除了使用PostMessage之外,找不到任何好的解决方案。
声明dll导入:
Imports System.Runtime.InteropServices
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function PostMessage(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Boolean
End Function
然后覆盖UserControl的ProcessCmdKey:
Protected Overrides Function ProcessCmdKey(ByRef msg As Message, ByVal keyData As Keys) As Boolean
'If ALT has been pressed...
If (keyData And Keys.Alt) > 0 Then
'... if another key is pressed aswell...
If (keyData Xor Keys.Alt) > 64 Then
'...pass the information to the container to see if it is interested
PostMessage(Me.ParentForm.Handle, CType(msg.Msg, UInt32), msg.WParam, msg.LParam)
Return True
End If
End If
'Not a key we are interested in
Return MyBase.ProcessCmdKey(msg, keyData)
End Function
如果您不能/不会进行P / Invoke,您可能会获得类似的效果,将焦点设置为父容器中的随机控件。
因此,将PostMessage替换为:
Me.ParentForm.Controls(0).Focus()
但是,这当然会将焦点转移到任何ALT /组合键上。