Entwickler-Ecke

WinForms - Navigieren mittels Pfeiltasten


Namenlosnameless - Sa 08.01.11 21:36
Titel: Navigieren mittels Pfeiltasten
Hallo!

Ich will für ein Projekt, einen "Cursor" mit den Pfeiltasten steuern.

Dieser Cursor wird auf einem Selbstgezeichnetem Raster herumgeschoben.
Ich kann wunderbar über W,A,S und D steuern, leider ist diese Lösung Suboptimal, da das Programm dann von der Bedienung unhandlich wird.

Ich hab das Problem: Wenn ich mit den Pfeiltasten steuern will (ich prüfe mit: if(e.KeyCode==Keys.Up) ) wird gleichzeitig der Fokus auf ein anderes Steuerelement gelegt und die if-Abfrage ergibt false bzw wird nicht angesteuert.

Wie kann ich, das Verschieben des Fokusses unterbinden?

mfg Christoph


Moderiert von user profile iconKha: Topic aus C# - Die Sprache verschoben am So 09.01.2011 um 20:03


Th69 - Sa 08.01.11 22:43

Hi,

setze in deinem KeyUp- bzw KeyDown-Ereignis noch zusätzlich "e.Handled":

C#-Quelltext
1:
2:
3:
4:
5:
if(e.KeyCode == Keys.Up)
{
   // ...
   e.Handled = true// Pfeiltaste als "behandelt" markieren
}


P.S. Alternativ auch "e.SuppressKeyPress = true".


Namenlosnameless - Sa 08.01.11 23:05

Danke für die Antwort!

Leider funktioniert, das nicht so wie du es geschrieben hast:

weil,


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
if (e.KeyCode == Keys.D || e.KeyCode == Keys.Right)
                {
                    e.Handled = true;


                    int x = selectedsquare.PosX;
                    int y = selectedsquare.PosY;
                    
                    x++;
                    if (x <= 9)
                    {
                        selectedsquare = playfield[(9 * (x - 1) + y - 1)];
                    }
                }


der Programmablauf nicht bis in die äußere if-Abfrage vordringt, also auch das e.Handled nicht.


EDIT: Okay ich habe gerade beim Debuggen bemerkt, dass das Drücken der Pfeiltasten, zwar den Fokus verschiebt, aber kein KeyDown-Event auslöst!


jaenicke - Sa 08.01.11 23:08

Windows fragt vorher mit WM_GETDLGCODE nach, ob diese Tastendrücke von dem Control behandelt werden sollen:
http://msdn.microsoft.com/en-us/library/ms645425(v=vs.85).aspx


Namenlosnameless - Sa 08.01.11 23:28

sry das ich so blöd frage,

aber ich verstehe nicht wirklich was WM_GETDLGCODE macht!
Wenn ich das richtig verstanden hab, sendet Windows diese Nachricht aus und ermittelt, dann aus der Antwort, was zu tun ist?


hab jetzt auch noch ein bisschen gegoogelt, es sind aber fast alle Seiten kopien der MSDN-Hilfe

kannst du mir das Ganz etwas genauer beschreiben?


jaenicke - Sa 08.01.11 23:40

Richtig, wenn eine solche Taste das erste Mal gedrückt wird, schickt Windows diese Message. Je nachdem was du in dieser Message zurückgibst, behandelt Windows diesen und folgende Tastendrücke entsprechend. Wenn du also DLGC_WANTARROWS zurückgibst, sagst du Windows damit, dass du diese Tastendrücke selbst behandeln willst.

Und dann bekommst du auch die entsprechenden Key-Messages, die dann nehme ich an auch zu den normalen C#-Events führen. (Ausprobiert habe ich das in C# noch nie.)


Namenlosnameless - Sa 08.01.11 23:51

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
(Ausprobiert habe ich das in C# noch nie.)


ich auch nicht :D

es klingt eigentlich ziemlich einfach.

Aber: wenn ich ehrlich bin, hab ich keinen Schimmer wie ich Windows mit DLGC_WANTARROWS antworten soll, bzw wie ich überhaupt die Frage abfange :S


jaenicke - Sa 08.01.11 23:59

Ich wusste es auch nicht, aber Google weiß wie man Windows Messages abfängt:
http://www.codeproject.com/KB/dotnet/devicevolumemonitor.aspx


Th69 - So 09.01.11 11:53

Hallo,

also bei mir funktioniert das wunderbar :D

Hätte erwähnen sollen, das man zusätzlich bei der Form "KeyPreview = true" setzen und du dann auch das KeyDown-Ereignis des Forms benutzen solltest (nicht des "Raster"-Controls wie z.B. Panel, PictureBox o.ä.).


Namenlosnameless - So 09.01.11 16:15

Das Raster wird direkt auf die Form gezeichnet :D

ich hab schon probiert bei allen Steuerelementen, das KeyDown-Ereignis abzufangen, aber wie gesagt, die Pfeiltasten rufen kein Ereignis hervor!
Das mit den Messages ist mir zwar immer noch nicht klar, aber ich werd weiter googeln ;D


Th69 - So 09.01.11 17:46

Hast du Buttons bei dir auf der Form? Du könntest auch einfach das 'Tabben' unterdrücken und für die Controls "TabStop = false" setzen.
Überprüfe auch mal ob wenigstens "Strg"- bzw. "Alt"- + Pfeiltasten in deine Methode springt.

Ansonsten gäbe es noch folgende Form-Methoden, welche du mittels Überschreiben benutzen könntest:
- ProcessCmdKey
- PreProcessMessage
- ProcessKeyMessage


jaenicke - So 09.01.11 20:36

Ok, man kann sich das Gehample mit der Windows Message sparen, da C# das schon übernimmt. Funktionieren tut es mit dem obigen Link aber auch damit. Einfacher ist es aber so (im Form selbst, KeyPreview auf true):

C#-Quelltext
1:
2:
3:
4:
        protected override bool ProcessDialogKey(Keys keyData)
        {
            return false;
        }
Dann funktioniert z.B. das normale KeyDown.


Namenlosnameless - So 09.01.11 21:23

jaenike: hat wunderbar funktioniert, Danke
Th69: ebenfalls Danke