面板未获得焦点

发布于 2024-09-16 05:11:25 字数 754 浏览 11 评论 0原文

我继续在我的简单图形程序中(使用 C#)编写某种键盘导航。而我又遇到了麻烦。

alt text

我的问题是我想处理键盘输入以移动图层。使用鼠标移动图层已经可以很好地工作,但控件未获得焦点(此控件既不会触发 KeyUp/KeyDown/KeyPress 也不会触发 GotFocus/LostFocus)。 由于我的类派生自Panel(并覆盖了几个事件),因此我也覆盖了上面提到的事件,但我无法成功触发这些事件。

我想我可以使用 Keyboard.GetState() 或 ProcessCmdWnd 之类的东西来实现键盘响应。但是:我仍然必须能够判断控件何时获得焦点。

是否有一种或多或少优雅的方式将此功能添加到用户控件(基于面板)?

我在这里检查了许多线程,我可能会使用这种方法用于键盘输入。然而焦点问题仍然存在。

非常感谢您提前提供信息!

伊戈尔.

ps:我正在使用 VS2008 使用 C# .NET v3.5 进行编程。它是一个 Windows.Forms 应用程序,不是 WPF

I am continuing to program some kind of keyboard navigation in my simple graphic program (using C#). And I ran into trouble once again.

alt text

My problem is that I want to process the keyboard input to move a layer around. Moving the layer with the mouse already works quite well, yet the control doesn't get the focus (neither KeyUp/KeyDown/KeyPress nor GotFocus/LostFocus is triggered for this control).
Since my class derives from Panel (and overwrites a couple of events), I've also overwritten the events mentioned above, but I can't succeed in getting those events triggered.

I think I could manage to implement keyboard response either using something like Keyboard.GetState() or ProcessCmdWnd or something. However: I still have to be able to tell when the control got the focus.

Is there an more or less elegant way to add this ability to a user control (which is based on Panel)?

I've checked many threads in here and I might use this approach for keyboard input. The focus problem however still remains.

Thank you very much for information in advance!

Igor.

p.s.: I am programming in C# .NET v3.5, using VS2008. It's a Windows.Forms application, not WPF.

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

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

发布评论

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

评论(6

魂ガ小子 2024-09-23 05:11:25

Panel 类被设计为容器,它避免获取焦点,因此子控件将始终获得焦点。你需要做一些手术来解决这个问题。我还添加了代码以在 KeyDown 事件中获取光标击键:

using System;
using System.Drawing;
using System.Windows.Forms;

class SelectablePanel : Panel {
    public SelectablePanel() {
        this.SetStyle(ControlStyles.Selectable, true);
        this.TabStop = true;
    }
    protected override void OnMouseDown(MouseEventArgs e) {
        this.Focus();
        base.OnMouseDown(e);
    }
    protected override bool IsInputKey(Keys keyData) {
        if (keyData == Keys.Up || keyData == Keys.Down) return true;
        if (keyData == Keys.Left || keyData == Keys.Right) return true;
        return base.IsInputKey(keyData);
    }
    protected override void OnEnter(EventArgs e) {
        this.Invalidate();
        base.OnEnter(e);
    }
    protected override void OnLeave(EventArgs e) {
        this.Invalidate();
        base.OnLeave(e);
    }
    protected override void OnPaint(PaintEventArgs pe) {
        base.OnPaint(pe);
        if (this.Focused) {
            var rc = this.ClientRectangle;
            rc.Inflate(-2, -2);
            ControlPaint.DrawFocusRectangle(pe.Graphics, rc);
        }
    }
}

The Panel class was designed as container, it avoids taking the focus so a child control will always get it. You'll need some surgery to fix that. I threw in the code to get cursor key strokes in the KeyDown event as well:

using System;
using System.Drawing;
using System.Windows.Forms;

class SelectablePanel : Panel {
    public SelectablePanel() {
        this.SetStyle(ControlStyles.Selectable, true);
        this.TabStop = true;
    }
    protected override void OnMouseDown(MouseEventArgs e) {
        this.Focus();
        base.OnMouseDown(e);
    }
    protected override bool IsInputKey(Keys keyData) {
        if (keyData == Keys.Up || keyData == Keys.Down) return true;
        if (keyData == Keys.Left || keyData == Keys.Right) return true;
        return base.IsInputKey(keyData);
    }
    protected override void OnEnter(EventArgs e) {
        this.Invalidate();
        base.OnEnter(e);
    }
    protected override void OnLeave(EventArgs e) {
        this.Invalidate();
        base.OnLeave(e);
    }
    protected override void OnPaint(PaintEventArgs pe) {
        base.OnPaint(pe);
        if (this.Focused) {
            var rc = this.ClientRectangle;
            rc.Inflate(-2, -2);
            ControlPaint.DrawFocusRectangle(pe.Graphics, rc);
        }
    }
}
Saygoodbye 2024-09-23 05:11:25

Hans Passant 的代码已翻译为 VB.NET

Imports System
Imports System.Drawing
Imports System.Windows.Forms

Public Class SelectablePanel
    Inherits Panel

    Public Sub New()
        Me.SetStyle(ControlStyles.Selectable, True)
        Me.TabStop = True
    End Sub
    
    Protected Overrides Sub OnMouseDown(ByVal e As MouseEventArgs)
        Me.Focus()
        MyBase.OnMouseDown(e)
    End Sub

    Protected Overrides Function IsInputKey(ByVal keydata As Keys) As Boolean
        If (keydata = Keys.Up OrElse keydata = Keys.Down) Then Return True
        If (keydata = Keys.Left OrElse keydata = Keys.Right) Then Return True
        Return MyBase.IsInputKey(keydata)
    End Function

    Protected Overrides Sub OnEnter(ByVal e As EventArgs)
        Me.Invalidate()
        MyBase.OnEnter(e)
    End Sub

    Protected Overrides Sub OnLeave(ByVal e As EventArgs)
        Me.Invalidate()
        MyBase.OnLeave(e)
    End Sub

    Protected Overrides Sub OnPaint(ByVal pe As PaintEventArgs)
        MyBase.OnPaint(pe)
        If (Me.Focused) Then
            Dim rc As Rectangle = Me.ClientRectangle
            rc.Inflate(-2, -2)
            ControlPaint.DrawFocusRectangle(pe.Graphics, rc)
        End If
    End Sub

End Class

The code from Hans Passant translated to VB.NET

Imports System
Imports System.Drawing
Imports System.Windows.Forms

Public Class SelectablePanel
    Inherits Panel

    Public Sub New()
        Me.SetStyle(ControlStyles.Selectable, True)
        Me.TabStop = True
    End Sub
    
    Protected Overrides Sub OnMouseDown(ByVal e As MouseEventArgs)
        Me.Focus()
        MyBase.OnMouseDown(e)
    End Sub

    Protected Overrides Function IsInputKey(ByVal keydata As Keys) As Boolean
        If (keydata = Keys.Up OrElse keydata = Keys.Down) Then Return True
        If (keydata = Keys.Left OrElse keydata = Keys.Right) Then Return True
        Return MyBase.IsInputKey(keydata)
    End Function

    Protected Overrides Sub OnEnter(ByVal e As EventArgs)
        Me.Invalidate()
        MyBase.OnEnter(e)
    End Sub

    Protected Overrides Sub OnLeave(ByVal e As EventArgs)
        Me.Invalidate()
        MyBase.OnLeave(e)
    End Sub

    Protected Overrides Sub OnPaint(ByVal pe As PaintEventArgs)
        MyBase.OnPaint(pe)
        If (Me.Focused) Then
            Dim rc As Rectangle = Me.ClientRectangle
            rc.Inflate(-2, -2)
            ControlPaint.DrawFocusRectangle(pe.Graphics, rc)
        End If
    End Sub

End Class
黑白记忆 2024-09-23 05:11:25

点击事件中调用焦点

private void Panel_Click(object sender, EventArgs e)
    {
        Panel.Focus();
    }

call focus in click event

private void Panel_Click(object sender, EventArgs e)
    {
        Panel.Focus();
    }
弃爱 2024-09-23 05:11:25

要获得焦点,请在“属性”窗口中检查 MouseEnter 事件。

写下下面的代码:

private void mainPanel_MouseEnter(object sender, EventArgs e)
{
    mainPanel.Focus();
}

To get the focus,check for MouseEnter event in Properties window.

Write below code:

private void mainPanel_MouseEnter(object sender, EventArgs e)
{
    mainPanel.Focus();
}
奈何桥上唱咆哮 2024-09-23 05:11:25

当由于任何原因我无法使用父 Form KeyPreview 属性来使 Form 处理按键事件时,我使用的最简单的技巧是在

面板上放置一个 Textbox:

Panel.Controls.Add(_focusTextBox = new TextBox() { Visible = true , Left = -300, TabIndex = 0});   

并使用它来捕获 KeyDown 事件:

_focusTextBox.KeyDown += panel_KeyDown;

最后一步是设置当面板上的其他控件单击时,焦点集中到此文本框:

_focusTextBox.Focus();

The simplest trick I use when for any reason I can’t use the parent Form KeyPreview property to make the Form handle key events, is to put a Textbox on

The panel:

Panel.Controls.Add(_focusTextBox = new TextBox() { Visible = true , Left = -300, TabIndex = 0});   

And use it to capture KeyDown event:

_focusTextBox.KeyDown += panel_KeyDown;

The last step is to set focus to this TextBox when other controls on the panel clicked:

_focusTextBox.Focus();
不美如何 2024-09-23 05:11:25

面板没有获得焦点,如果您想跟踪离开和输入事件,则必须选择面板,

MouseClick 事件中调用 panel1.Select()

Panels are not getting focus, you have to select the panel if you want to track leave and enter events

call panel1.Select() in MouseClick Event

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