Autor Beitrag
avoid
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 230
Erhaltene Danke: 4

MSDos, WinXP32, Win764, Win10, Android, Debian
msl (mIRC edit), html & php & Java (DreamweaverMX), Basic (picaxe PE6), C (Arduino IDE), C# (vs2010,2015,2017,2019,Unity,Android Studio)
BeitragVerfasst: So 24.08.14 12:49 
Ich versuche mir mal wieder ein par Grundlagen an zu eignen.
Wie man in meinem Code sehen kann bewege ich eine PictureBox, mittels Pfeiltasten, auf einem Form herum.
Dazu verwende ich neben der PictureBox nur noch einen Timer, damit die Bewegung flüssiger wird.

Meine Frage ist:
Wie kann ich sicherstellen das sich die PictureBox noch bewegen lässt,
wenn noch andere Controls auf der Form sind z. b. eine TextBox.

Gibt es da ein Problem mit dem Focus oder eher mit der Tastenabfrage?
Mir ist übrigens aufgefallen das die Form und die PictureBox keinen TabIndex besitzen ...


ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
public partial class Form1 : Form
{
    bool RightDown = false;
    bool LeftDown = false;
    bool UpDown = false;
    bool DownDown = false;

    public Form1()
    {
        InitializeComponent();
        KeyDown += new KeyEventHandler(Form1_KeyDown);
        KeyUp += new KeyEventHandler(Form1_KeyUp);
        pictureBox1.BackColor = Color.Blue;
        timer1.Interval = 1;
        timer1.Tick += new EventHandler(timer1_Tick);
    }

    private void Form1_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.KeyCode == Keys.Right) RightDown = true;
        else if (e.KeyCode == Keys.Left) LeftDown = true;
        else if (e.KeyCode == Keys.Up) UpDown = true;
        else if (e.KeyCode == Keys.Down) DownDown = true;
        if (RightDown == true || LeftDown == true || UpDown == true || DownDown == true)
        {
            timer1.Enabled = true;
        }
    }

    private void Form1_KeyUp(object sender, KeyEventArgs e)
    {
        if (e.KeyCode == Keys.Right) RightDown = false;
        else if (e.KeyCode == Keys.Left) LeftDown = false;
        else if (e.KeyCode == Keys.Up) UpDown = false;
        else if (e.KeyCode == Keys.Down) DownDown = false;
        if (RightDown == false && LeftDown == false && UpDown == false && DownDown == false)
        {
            timer1.Enabled = false;
        }
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        int x = pictureBox1.Location.X;
        int y = pictureBox1.Location.Y;

        if (RightDown == true) x += 1;
        if (LeftDown == true) x -= 1;
        if (UpDown == true) y -= 1;
        if (DownDown == true) y += 1;

        pictureBox1.Location = new Point(x, y);
    }
}

_________________
Gute Fragen sind wie ein wissenschaftliches Experiment. Sie setzen eine Menge Wissen bereits voraus.
bitcoin:1J5dgQQp8eUy8wkUxyztBUVCkCpo5MQEQs?label=Danke
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4701
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: So 24.08.14 13:22 
Zitat:
Gibt es da ein Problem mit dem Focus oder eher mit der Tastenabfrage?
Mir ist übrigens aufgefallen das die Form und die PictureBox keinen TabIndex besitzen ...


Problem würde ich es nicht nennen. Es ist normal das man Controls mit denen man eigentlich nicht interagiert nicht fokussieren kann. Daher macht auch ein Focus verschieben via Tab dorthin keinen Sinn ergo kein TabIndex nötig.

Sobald ein Control den Focus hat (zum Beispiel eine Textbox) bekommt dieses Control die Key Events und die der Form werden nicht verwendet. In deinem Rahmen sollte es helfen KeyPreview der Form auf true zu setzen. Dann sollte zumindest von allen üblichen Controls die den Focus haben können die Key Events auch an die Form weitergeleitet werden.

Für diesen Beitrag haben gedankt: avoid
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: So 24.08.14 13:56 
Hallo avoid,

Stichwort: Form.KeyPreview

Für diesen Beitrag haben gedankt: avoid
avoid Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 230
Erhaltene Danke: 4

MSDos, WinXP32, Win764, Win10, Android, Debian
msl (mIRC edit), html & php & Java (DreamweaverMX), Basic (picaxe PE6), C (Arduino IDE), C# (vs2010,2015,2017,2019,Unity,Android Studio)
BeitragVerfasst: Mo 25.08.14 14:08 
Danke Ralf, für die gute erklärung.
Na dann mach ich mich mal über KeyPreview schlau.
Danke Th69 für denk Link

_________________
Gute Fragen sind wie ein wissenschaftliches Experiment. Sie setzen eine Menge Wissen bereits voraus.
bitcoin:1J5dgQQp8eUy8wkUxyztBUVCkCpo5MQEQs?label=Danke
avoid Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 230
Erhaltene Danke: 4

MSDos, WinXP32, Win764, Win10, Android, Debian
msl (mIRC edit), html & php & Java (DreamweaverMX), Basic (picaxe PE6), C (Arduino IDE), C# (vs2010,2015,2017,2019,Unity,Android Studio)
BeitragVerfasst: Mi 27.08.14 20:56 
ich hab mir das Beispiel von MSDN heute mal angesehen und versucht nach zu vollziehen aber ich hab noch zwei fragen dazu.

1. was genau bewirkt KeyPreview?
MSDN widerspricht sich in der Beschreibung selbst.
An einer stelle steht das es dem Form ermöglicht Eingaben zu verarbeiten bevor sie an das Control mit dem Focus weiter gereicht werden.
An einer anderen stelle steht das die Eingaben nach der Bearbeitung durch das fokussierte Control an das Formular weiter gereicht werden.

2. was genau bewirken die KeyEventArgs in diesem Zusammenhang?
benutze ich die im MSDN Beispiel verwendete Codezeile und setze e.Handled auf false dann ändert sich nichts.
setze ich aber e.Handled auf true dann werden im fall meines Code z. b. Buchstaben an eine TextBox mit Focus übergeben die Pfeiltasten aber nicht.

kann mir jemand noch etwas mehr Input dazu geben, damit ich die zusammenhänge verstehe?

_________________
Gute Fragen sind wie ein wissenschaftliches Experiment. Sie setzen eine Menge Wissen bereits voraus.
bitcoin:1J5dgQQp8eUy8wkUxyztBUVCkCpo5MQEQs?label=Danke
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Mi 27.08.14 21:17 
KeyPreview = true bewirkt, daß zuerst das Form(ular) die Tastatureingaben empfängt, bevor sie an das fokussierte Control gehen. Daher kann man dann auf Pfeiltasten im Form reagieren, weil sonst die TextBox die Pfeiltasten bearbeiten würde.
Und mit e.Handled = true im Eventhandler kann man dann dafür sorgen, daß die Message-Weiterleitung unterbrochen wird (wenn du so bei den Pfeiltasten reagierst, wird die Eingabe z.B. nicht mehr an die TextBox weitergeleitet).
e.Handled = false bewirkt dagegen nichts, da dies schon die Default-Einstellung ist. ;-)

Für diesen Beitrag haben gedankt: avoid
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4701
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mi 27.08.14 21:47 
Zitat:
An einer stelle steht das es dem Form ermöglicht Eingaben zu verarbeiten bevor sie an das Control mit dem Focus weiter gereicht werden.
An einer anderen stelle steht das die Eingaben nach der Bearbeitung durch das fokussierte Control an das Formular weiter gereicht werden.


Das ist nur scheinbar widersprüchlich und der 2.te Satz wenn der so in der Hilfe steht vermutlich eher einer schlechten Übersetzung geschuldet.

Windows sendet WindowMessages immer direkt an Controls. Also wenn eine TextBox den Focus hat gehen die Messages (z.b Key messages) an diese TextBox. Immer. Aber durch KeyPreview gaukelt Winforms was anderes vor. Denn das Control das die Message bekommen hat wird seine ParentForm prüfen ob KeyPreview gesetzt ist und wenn ja dann die Message an die Form weiterleiten bevor es selbst was damit anfängt.
Wenn der entsprechende Event auf der Form abgearbeitet ist wird das Control prüfen ob Handled gesetzt ist und im Fall des Falles selbst noch de Message bearbeiten oder es eben lassen. Der Flow der Key Message wäre also Windows -> Control -> Form -> Control wenn KeyPreview gesetzt ist. Das Control ist also vor und nach der Form beteiligt.

Darum sprach ich in meiner ersten Antwort auch so wolkig davon das KeyPreview bei allen üblichen Controls funktionieren sollte. Bei schlecht selbst implementierten oder schlechten Third Party Controls könnte diese Logik überschrieben sein und das Routen an die ParentForm nicht funktionieren womit dann KeyPreview hinfällig ist (zugegebenermaßen muss man sich schon anstrengen und tief eingreifen um das hinzubekommen).

Für diesen Beitrag haben gedankt: avoid
avoid Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 230
Erhaltene Danke: 4

MSDos, WinXP32, Win764, Win10, Android, Debian
msl (mIRC edit), html & php & Java (DreamweaverMX), Basic (picaxe PE6), C (Arduino IDE), C# (vs2010,2015,2017,2019,Unity,Android Studio)
BeitragVerfasst: Mi 27.08.14 22:42 
nochmal danke an euch beide.

Kurz zusammengefasst:
Ich gebe mit KeyPreview = true an, dass das Form vor den Controls die Eingabe verarbeiten darf.
Ich kann dann im entsprechenden Event des Form mit e.Handled = true angeben das die Eingabe bearbeitet wurde so das sich das Control nicht weiter damit befasst.
Soll die Eingabe trotzdem zusätzlich/ausschließlich vom Control verarbeitet werden lasse ich e.Handled = false.

Also sollte ich im KeyDown Event am besten als erstes abfragen ob es sich um eine Taste handelt die vom Form oder dem Control verarbeitet werden soll.

e.Handled = true alleine scheint aber nicht zu genügen selbst wenn es am ende des KeyDown Event steht,
weil ich trotzdem noch Buchstaben und Zahlen in die TextBox eingebe und diese nicht komplett abfange.
Aber das finde ich noch raus.

schöne Sache :)

---nachtrag---

e.SuppressKeyPress = true ist die Lösung!
Damit kann man den Controls, die Tasten komplett vorenthalten.
Zitat:
Sie können true dieser Eigenschaft in einem Ereignishandler zuweisen, z. B.KeyDown, um die Benutzereingabe zu verhindern.
Durch Festlegen von SuppressKeyPress auf true wird auch Handled auf true festgelegt.

_________________
Gute Fragen sind wie ein wissenschaftliches Experiment. Sie setzen eine Menge Wissen bereits voraus.
bitcoin:1J5dgQQp8eUy8wkUxyztBUVCkCpo5MQEQs?label=Danke