Tastatur Events an der richtigen Stelle verarbeiten

Mal wieder etwas das man wissen sollte, einen aber Unmengen Zeit kostet wenn man’s nicht weiss.

Folgendes Szenario: Windows Forms Applikation mit einer Listbox.

Ich möchte auf die Page-Up und Page-Down Tasten unabhängig von dieser ListBox auswerten.
Allerdings gehen die KeyDown Events IMMER an die ListBox, die auf ein Page-Down natürlich mit herunterscrollen reagiert, was sie aber nicht soll. Focus auf die Form des Hauptfensters setzen hilft da gar nicht.

Microsoft liefert die Erklärung: Sobald eine Form ein Control wie eine ListBox enthält, gehen die Events ausschliesslich an die Controls. Nur eine Form ohne Controls erhält Key-Events.

Dieses Verhalten zu ändern ist denkbar einfach: Man setzt die Eigenschaft KeyPreview der Form auf True!

Damit gehen dann alle Key-Events immer zuerst an die Form und werden danach an die Controls weitergegeben.
Falls man die Weitergabe auch noch verhindern möchte, setzt man die Handled Eigenschaft des KeyEventArgs auf true. Dann bekommen die Controls von der gedrückten Taste nichts mehr mit.

Der Event Handler der Form sieht dann so aus:

        private void frontend_keydown(object sender, KeyEventArgs e)
        {
            switch(e.KeyCode)
            {
                case Keys.PageUp:
                    {
                        e.Handled = true;
                        break;
                    }
            }
        }
private void frontend_keydown(object sender, KeyEventArgs e)
{
switch(e.KeyCode)
{
case Keys.Escape:
{
CloseVideo();
this.Close();
break;
}case Keys.MediaPlayPause:
{
PauseClip();
break;
}

case Keys.PageUp:
case Keys.MediaNextTrack:
{
if ((this.isFullScreen == true) && (this.currentState == PlayState.Running) && (this.mediaSeeking != null))
{
long pos;
float currentPos;
int hr = 0;

hr = this.mediaSeeking.GetCurrentPosition(out pos);
currentPos = Convert.ToSingle(pos) / 10000000; // pos is returned in units of 100 nanoseconds, chapters are in seconds

for (int i = 0; i < this.chapterCount; i++)
{
if (this.chapterTime[i] > currentPos)
{
pos = Convert.ToInt64(this.chapterTime[i] * 10000000);
hr = this.mediaSeeking.SetPositions(pos, AMSeekingSeekingFlags.AbsolutePositioning, null, AMSeekingSeekingFlags.NoPositioning);
break;
}
}
e.Handled = true;
}
break;
}

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.