windows - C # fokuserer på formularer og piletaster

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg vil gerne lave en korteditor til et spil. Det er et program, der vil have Windows Forms UI (som PropertyGrid for at redigere objektets egenskaber), men det vil også have et panel på hvilket kort der vil blive tegnet.


Hvad jeg vil:


Når fokus er på panelet med kortet, vil jeg gerne bruge tastaturet til at flytte kortet rundt (piletasterne), tilføje objekter (nummertaster) osv. Når fokus ikke findes på dette panel, synes jeg, at knapperne fungerer som Normal i Windows-formularer - Tillad fanen mellem kontroller mv.


Min form ser sådan ud:


Den har en ToolStripControl, der har en menuStrip (til hovedmenuen) og en statusStrip (for statuslinjen). Midt i formularen (eller toolstripcontrol) er SplitControl docked (dock=fill), der har to paneler. Panel 1 har PanelMap - et panel, der viser kortet. Panel 2 har alle andre ting som propertygrid, tabcontrols, knapper osv.


Jeg har KeyPreview af form sat til ægte og proces tastatur begivenheder i formens keydown event handler.


Hvad sker der nu, hvis jeg tildeler fokus til PanelMap, næste gang jeg trykker på en piletast, brænder INGEN KeyDown-begivenhed ikke. Ikke en enkelt! Selv form, som skal behandle alle begivenheder, fordi den har 'KeyPreview', får den ikke til at blive ild. Når jeg trykker på en pil, taber PanelMap fokus mod SplitControl.


Okay, jeg troede, at PanelMap måske aldrig har fokus, lad os fokusere på SplitControl (hvis jeg trykker på piletasten, mens den har fokus, kan jeg klare det, så det går ikke længere). Men så, hvis noget som en tekstboks inde i noget, der er inde i SplitControl har fokus, så kan SplitControl IKKE få fokus. .Focus () vil ikke gøre noget - fokus forbliver i den kontrol, der havde det!


Hvorfor virker det så mærkeligt? Hvorfor presses ikke Formens KeyDown-brand, når panelet har fokus og piletast? Hvorfor bliver ikke SplitControl fokuseret, når jeg kalder .Focus (), selvom CanFocus=true?


Og i sidste ende, hvordan opnår jeg det, jeg vil have? Er der en måde at gøre det på?

Bedste reference


Jeg tror, ​​du 'kører ind i widgetsne, der tager tastetrykket, før dine begivenheder kommer til dem til navigation. Jeg havde dette problem og gjorde det her:


    private void RemoveCursorNavigation(Control.ControlCollection controls)
    {
        foreach(Control ctrl in controls)
        {
            ctrl.PreviewKeyDown += new PreviewKeyDownEventHandler(MainWin\_PreviewKeyDown);
            RemoveCursorNavigation(ctrl.Controls);
        }
    }


Jeg kalder denne funktion i hovedformularen 's Load Handler, som denne:


RemoveCursorNavigation(this.Controls);


I din PreviewKeyDown handler skal du gøre dette:


    public void MainWin\_PreviewKeyDown(Object sender, PreviewKeyDownEventArgs e)
    {
        switch(e.KeyCode)
        {
            case Keys.Up:
            case Keys.Down:
            case Keys.Left:
            case Keys.Right:
                e.IsInputKey = true;
                break;
            default:
                break;
        }
    }


e.IsInputKey = true; fortæller ydersiden, at du har brugt denne begivenhed, og vil ikke have det til at gå andre steder.


Nu får du se tastetrykket, før de går til widgetsne, og du vil ikke få navigation mellem dem fra markørtasterne.

Andre referencer 1


Jeg fandt et svar som dette:


Jeg lavede en tekstboks, der er gemt under et panel (men aktiveret og synligt). Denne tekstfelt er fokuseret, når jeg vil 'låse' fokus på min PanelMap. Den har onkeydown selv med e.suppress=true, så tekstboksen aldrig får tastetryk for at påvirke det.


Rå opløsning, men arbejder vidundere ... typisk M $ forretning ...