it-swarm.com.de

Panel bekommt keinen Fokus

Ich programmiere weiterhin eine Art Tastaturnavigation in meinem einfachen Grafikprogramm (mit C #). Und ich hatte wieder einmal Ärger.

alt text

Mein Problem ist, dass ich die Tastatureingaben verarbeiten möchte, um eine Ebene zu verschieben. Das Verschieben der Ebene mit der Maus funktioniert bereits recht gut, jedoch erhält das Steuerelement nicht den Fokus ( weder KeyUp/KeyDown/KeyPress noch GotFocus/LostFocus wird für dieses Steuerelement ausgelöst ). Since Meine Klasse stammt von Panel (und überschreibt einige Ereignisse), ich habe auch die oben genannten Ereignisse überschrieben, aber es ist mir nicht möglich, diese Ereignisse auszulösen.

Ich denke, ich könnte es schaffen, die Tastaturantwort entweder mit Keyboard.GetState () oder ProcessCmdWnd oder so etwas zu implementieren. Allerdings: Ich muss immer noch erkennen können, wann das Steuerelement den Fokus hat.

Gibt es eine mehr oder weniger elegante Möglichkeit, diese Fähigkeit zu einem Benutzersteuerelement hinzuzufügen (das auf Panel basiert)?

Ich habe hier viele Threads eingecheckt, und ich könnte diesen Ansatz für die Tastatureingabe verwenden. Das Fokusproblem bleibt jedoch bestehen.

Vielen Dank für die Information im Voraus!

Igor.

p .: Ich programmiere in C # .NET v3.5 mit VS2008. Es ist eine Windows.Forms-Anwendung, nicht WPF .

26
Igor

Die Panel-Klasse wurde als Container entworfen. Sie vermeidet den Fokus, sodass ein untergeordnetes Steuerelement diesen immer erhält. Sie müssen operiert werden, um das zu beheben. Ich habe den Code hineingeworfen, um auch im KeyDown-Ereignis die Cursortasten zu markieren:

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);
        }
    }
}
57
Hans Passant

Derselbe Hans Passant-Code in VB.NET

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

Public Class SelectablePanel
    Inherits Panel

    Public Sub SelectablePanel()
        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
6
Oliver Miranda

Der einfachste Trick, den ich verwende, wenn ich aus irgendeinem Grund die übergeordnete Form KeyPreview-Eigenschaft nicht dazu verwenden kann, Formularereignisschlüsselereignisse auszuführen, ist das Einfügen eines Textfelds 

Das Panel:

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

Und verwenden Sie es, um ein KeyDown-Ereignis zu erfassen:

_focusTextBox.KeyDown += panel_KeyDown;

Der letzte Schritt besteht darin, den Fokus auf dieses Textfeld zu setzen, wenn auf andere Steuerelemente im Bedienfeld geklickt wird:

_focusTextBox.Focus();
0
Eng. M.Hamdy

rufen Sie den Fokus im Klick-Ereignis auf

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

Um den Fokus zu erhalten, überprüfen Sie das MouseEnter-Ereignis im Eigenschaftenfenster.

Schreiben Sie den folgenden Code:

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