vb.net - Alt 代码没有导航出用户控制

标签 vb.net winforms

在我们应用程序的主要处理表单中,我们使用 alt 代码(例如,将 &Label 作为标签文本以使用 Alt-L 快速导航到控件)进行快速导航,以便在用户需要离开时在屏幕上跳转传统的导航流程 - 但最近我们遇到了障碍:

我们有一个在表单上处理相当多的用户控件,其中有一个控件需要与用户控件之外的另一个控件共享一个 alt-code (Alt-R)。通常,这不是问题,因为我们可以将它们都设置为 Alt-R,Alt-R 会在两者之间切换。由于其中一个控件在用户控件内,而另一个不在用户控件内,因此一旦焦点在用户控件内,它就不会在用户控件外切换,两个控件共享一个 Alt 代码。

是否有任何我可以设置的属性允许这样做而无需编写自定义逻辑来处理?自定义逻辑的主要问题是其中一些 alt 代码可以由用户定义,当我认为这应该正常工作时,编写一个包罗万象的处理方法并不是理想的选择在普通的 Windows 窗体引擎中

最佳答案

除了为此使用 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/组合键的焦点。

关于vb.net - Alt 代码没有导航出用户控制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47677572/

相关文章:

mysql - 集成安全 MySQL/VB.NET

VB.NET WinForms - 如何从BackgroundWorker的线程访问主线程的对象?

c# - Designer 在 InitializeComponent 中创建一些字段而不是创建全局变量

c# - 在 C# 中的标签中显示全文

c# - ASP.NET 和 JavaScript 错误

vb.net - 获取目录中的所有文件夹和子文件夹

c# - WinForm c# : Check first run and show message

c# - 无法访问具有数据集和表适配器的 GridView

vb.net - 使用串口转 USB 开关控制程序

c# - Winforms 中的 Explorer.exe 浏览网络文件夹