Laden...

[gelöst] PreviewKeyDown für alle Steuerelemente!

Erstellt von Da_Flo vor 14 Jahren Letzter Beitrag vor 14 Jahren 2.104 Views
D
Da_Flo Themenstarter:in
269 Beiträge seit 2009
vor 14 Jahren
[gelöst] PreviewKeyDown für alle Steuerelemente!

hallo!

ich hätte in einer foreach schleife einfach alle controls durchgelaufen und hätte ein previewKeyDown ereigniss hinzugefügt. Nun bin ich draufgekommen(beim testen), dass es ja Controls gibt (groupBox, etc) die wiederum Controls enthalten

so hätte ich mal das probiert:

public void initialize()
        {
            foreach (Control ctrl in Controls)
            {
                ctrl.PreviewKeyDown += new PreviewKeyDownEventHandler(ctrl_PreviewKeyDown);
                foreach (Control ctrl1 in ctrl.Controls)
                {
                    ctrl1.PreviewKeyDown += new PreviewKeyDownEventHandler(ctrl_PreviewKeyDown);
                    foreach (Control ctrl2 in ctrl1.Controls)
                    {
                        ctrl2.PreviewKeyDown += new PreviewKeyDownEventHandler(ctrl_PreviewKeyDown);
                        foreach (Control ctrl3 in ctrl2.Controls)
                        {
                            ctrl3.PreviewKeyDown += new PreviewKeyDownEventHandler(ctrl_PreviewKeyDown);
                            
                        }
                    }
                }
            }
        }

das problem hier ist ich weis ja nie wie "weit" ich hineingehen muss um an der untersten ebene der controls anzukommen.

jez hätte ich das ganze mal mit rekursion probiert(was ich glaube ich der richtige ansatz wäre), doch irgendetwas haut noch nicht so hin wie ich das möchte, es wird nicht bei allen elementen das KeyDown ereigniss hinzugefügt!

hier mit rekursion:

 public void initialize()
        {
            this.PreviewKeyDown += new PreviewKeyDownEventHandler(ctrl_PreviewKeyDown);
            if (this.HasChildren)
            {
                initializeChildren(this);
            }
        }
        private void initializeChildren(Control ctrl)
        {
            foreach (Control cntrl in ctrl.Controls)
            {
                ctrl.PreviewKeyDown += new PreviewKeyDownEventHandler(ctrl_PreviewKeyDown);
                if (cntrl.HasChildren)
                {
                    initializeChildren(cntrl);
                }
            }
        }

danke
Flo

5.299 Beiträge seit 2008
vor 14 Jahren

Du abbonnierst für jeden Child, aber leider das event des Parents (also mehrfach dasselbe).

Probiermaso:


      public void initialize() {
         this.PreviewKeyDown += new PreviewKeyDownEventHandler(ctrl_PreviewKeyDown);
         initializeChildren(this.Controls);
      }
      private void initializeChildren(Control.ControlCollection ctrls) {
         foreach (Control ctrl in ctrls) {
            ctrl.PreviewKeyDown += new PreviewKeyDownEventHandler(ctrl_PreviewKeyDown);
            initializeChildren(ctrl.Controls);
         }
      }

Hiernochwas zu Rekursion ühaupt: Bäume durchlaufen mit Rekursion

Zu beachten auch, dass glaub manche controls ihr PreviewKeyDown deaktiviert haben.

Der frühe Apfel fängt den Wurm.

D
Da_Flo Themenstarter:in
269 Beiträge seit 2009
vor 14 Jahren

Danke! so funktionert es nun wunderbar 😉

R
344 Beiträge seit 2006
vor 14 Jahren

Hallo alle,

da ich dies brauchte und es wunderbar funktioniert, habe ich es noch etwas erweitert.

Und zwar habe ich zunächst das gleiche auch für KeyUp gemacht.

        public void initialize()
        {
            this.PreviewKeyDown += new PreviewKeyDownEventHandler(ctrl_PreviewKeyDown);
            this.KeyUp += new KeyEventHandler(Form1_KeyUp);
            initializeChildren(this.Controls);
        }

        private void initializeChildren(Control.ControlCollection ctrls)
        {
            foreach (Control ctrl in ctrls)
            {
                ctrl.PreviewKeyDown += new PreviewKeyDownEventHandler(ctrl_PreviewKeyDown);
                ctrl.KeyUp += new KeyEventHandler(Form1_KeyUp);
                initializeChildren(ctrl.Controls);
            }
        }
        private void ctrl_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
        {
            zeichnung1.KeyDownVonForm(sender, e);
        }
        void Form1_KeyUp(object sender, KeyEventArgs e)
        {
            zeichnung1.KeyUpVonForm(sender, e);
        }

Dann in dem Control, in dem ich es haben wollte zwei Funktionen gemacht.

        public void KeyDownVonForm(object sender, PreviewKeyDownEventArgs e)
        {
            myKeys[e.KeyCode] = true;
        }
        public void KeyUpVonForm(object sender, KeyEventArgs e)
        {
            myKeys[e.KeyCode] = false;
        }

Vorher musste ich mir ein Dictionary anlegen und es im Konstuktor des Controls füllen.

        Dictionary<Keys, bool> myKeys = new Dictionary<Keys, bool>();
        public Zeichnung()
        {
            foreach (Keys e in Enum.GetValues(typeof(Keys)))
            {
                myKeys[e] = false;
            }
         }

Jetzt habe ich überall im Control die gerade gedrückten Tasten vorliegen.

Test mit:

                string labelText = "";
                foreach (KeyValuePair<Keys, bool> item in myKeys)
                {
                    if (item.Value)
                    {
                        labelText += "  "+item.Key.ToString();
                    }
                    
                } 
                label1.Text = labelText;

Gruß Robert