La mejor manera de implementar atajos de teclado en una aplicación de Windows Forms?


Estoy buscando una mejor manera de implementar comunes de Windows atajos de teclado (por ejemplo Ctrl+F, Ctrl+N) en mi Formularios Windows forms aplicación en C#.

La aplicación tiene un formulario principal que alberga muchos formularios secundarios (uno a la vez). Cuando un usuario pulsa Ctrl+F , me gustaría mostrar un formulario de búsqueda personalizado. El formulario de búsqueda dependería del formulario hijo abierto actual en la aplicación.

Estaba pensando en usar algo como esto en el evento ChildForm_KeyDown :

   if (e.KeyCode == Keys.F && Control.ModifierKeys == Keys.Control)
        // Show search form

Pero esto no funciona. El evento ni siquiera se dispara cuando presionas una tecla. ¿Cuál es la solución?

Author: Peter Mortensen, 2008-12-30

11 answers

Probablemente olvidó establecer la propiedad KeyPreview en True. Sobreescribir el método ProcessCmdKey () es la solución genérica:

protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
  if (keyData == (Keys.Control | Keys.F)) {
    MessageBox.Show("What the Ctrl+F?");
    return true;
  }
  return base.ProcessCmdKey(ref msg, keyData);
}
 416
Author: Hans Passant,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-29 13:47:45

En su formulario principal

  1. Establecer KeyPreview a Verdadero
  2. Agregue el controlador de eventos KeyDown con el siguiente código

    private void MainForm_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.Control && e.KeyCode == Keys.N)
        {
            SearchForm searchForm = new SearchForm();
            searchForm.Show();
        }
    }
    
 62
Author: Almir,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-29 13:06:48

La mejor manera es usar mnemotécnica de menú, es decir, tener entradas de menú en su formulario principal a las que se les asigna el atajo de teclado que desea. Entonces todo lo demás se maneja internamente y todo lo que tiene que hacer es implementar la acción apropiada que se ejecuta en el controlador de eventos Click de esa entrada de menú.

 17
Author: Konrad Rudolph,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-30 12:06:27

Incluso puedes probar este ejemplo:

public class MDIParent : System.Windows.Forms.Form
{
    public bool NextTab()
    {
         // some code
    }

    public bool PreviousTab()
    {
         // some code
    }

    protected override bool ProcessCmdKey(ref Message message, Keys keys)
    {
        switch (keys)
        {
            case Keys.Control | Keys.Tab:
              {
                NextTab();
                return true;
              }
            case Keys.Control | Keys.Shift | Keys.Tab:
              {
                PreviousTab();
                return true;
              }
        }
        return base.ProcessCmdKey(ref message, keys);
    }
}

public class mySecondForm : System.Windows.Forms.Form
{
    // some code...
}
 11
Author: Shilpa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-30 10:01:41

Si tiene un menú, entonces cambiar ShortcutKeys propiedad de la ToolStripMenuItem debería hacer el truco.

Si no, puede crear uno y establecer su propiedad visible en false.

 8
Author: Corin Blaikie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-07 11:53:24

La respuesta de Hans podría ser un poco más fácil para alguien nuevo en esto, así que aquí está mi versión.

No necesitas engañar con KeyPreview, déjalo en false. Para usar el código a continuación, simplemente péguelo debajo de su form1_load y ejecute F5 para verlo funcionar:

protected override void OnKeyPress(KeyPressEventArgs ex)
{
    string xo = ex.KeyChar.ToString();

    if (xo == "q") //You pressed "q" key on the keyboard
    {
        Form2 f2 = new Form2();
        f2.Show();
    }
}
 4
Author: Abhishek Jha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 10:31:14

Desde el Formulario principal, tienes que:

  • asegúrese KeyPreview a true( TRUE por defecto)
  • Add MainForm_KeyDown (..)- por el que se puede establecer aquí cualquier atajo que desee.

Además,he encontrado esto en Google y quería compartir esto con aquellos que todavía están buscando respuestas. (para mundial)

Creo que tienes que estar usando user32.dll

protected override void WndProc(ref Message m)
{
    base.WndProc(ref m);

    if (m.Msg == 0x0312)
    {
        /* Note that the three lines below are not needed if you only want to register one hotkey.
         * The below lines are useful in case you want to register multiple keys, which you can use a switch with the id as argument, or if you want to know which key/modifier was pressed for some particular reason. */

        Keys key = (Keys)(((int)m.LParam >> 16) & 0xFFFF);                  // The key of the hotkey that was pressed.
        KeyModifier modifier = (KeyModifier)((int)m.LParam & 0xFFFF);       // The modifier of the hotkey that was pressed.
        int id = m.WParam.ToInt32();                                        // The id of the hotkey that was pressed.


        MessageBox.Show("Hotkey has been pressed!");
        // do something
    }
}

Siga leyendo esto http://www.fluxbytes.com/csharp/how-to-register-a-global-hotkey-for-your-application-in-c/

 4
Author: Juran,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-30 10:02:09

En WinForm, siempre podemos obtener el estado de la Clave de control mediante:

bool IsCtrlPressed = (Control.ModifierKeys & Keys.Control) != 0;
 1
Author: s k,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-31 08:30:05
 private void Form1_KeyDown(object sender, KeyEventArgs e)
    {
        if(e.Alt == true && e.KeyCode == Keys.A)
        {
            button1ADD.PerformClick();
        }

        if(e.Alt == true && e.KeyCode == Keys.D)
        {
            button2DeleteaaLL.PerformClick();
        }

        if(e.Alt == true && e.KeyCode == Keys.S)
        {
            Deleteselectedbtn.PerformClick();

        }

        if(e.Alt == true && e.KeyCode == Keys.C)
        {
            button4Close.PerformClick();
        }

    }

    private void Form1_Shown(object sender, EventArgs e)
    {
        txtInput.Focus();




    }

    private void button1ADD_Click(object sender, EventArgs e)
    {
        if(!string.IsNullOrEmpty(txtInput.Text))
        {
            Listmylist.Items.Add(txtInput.Text);
            txtInput.Clear();
            txtInput.Focus();
        }
    }


    private void button2DeleteaaLL_Click(object sender, EventArgs e)
    {
        Listmylist.Items.Clear();
        txtInput.Focus();
    }

    private void Deleteselectedbtn_Click(object sender, EventArgs e)
    {
        Listmylist.Items.RemoveAt(Listmylist.SelectedIndex);
        txtInput.Focus();

    }

    private void button4Close_Click(object sender, EventArgs e)
    {
        Application.Exit();
    }

    private void txtInput_TextChanged(object sender, EventArgs e)
    {
        button1ADD.Enabled = true;

    }
 0
Author: 122,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-10 05:07:23
private void buttonCheck_Click_1(object sender, EventArgs e)
    {
        bool jeElement = false;

        for (int i = 0; i < listBox1.Items.Count; i++)
        {
            if (textBox1.Text == listBox1.Items[i].ToString())
            {
                jeElement = true;
                break;
            }
        }
        if (jeElement)
        {
            label1.Text = "je element";
        }
        else
        {
            label1.Text = "ni element";
        }
        textBox1.ResetText();
        textBox1.Focus();

    }

    private void Form1_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.Alt == true && e.KeyCode == Keys.A)
        {
            buttonCheck.PerformClick();
        }
    }
}
}

    private void timer1_Tick(object sender, EventArgs e)
    {
        if (radioButtonF.Checked)
        {
            progressBar1.Value++;
        }
        else
        {
            progressBar1.Value--;
        }

        if (progressBar1.Value == progressBar1.Maximum)
        {
            timer1.Stop();
            label1.Text = "End";
        }

        if (progressBar1.Value == progressBar1.Minimum)
        {
            timer1.Stop();
            label1.Text = "Begining";
        }
    }

    private void radioButtonF_CheckedChanged(object sender, EventArgs e)
    {
        timer1.Start();
        progressBar1.Value = 0;
        progressBar1.Maximum = 100;
    }

    private void radioButtonB_CheckedChanged(object sender, EventArgs e)
    {
        timer1.Start();
        progressBar1.Value = 100;
        progressBar1.Minimum = 0;
    }
}
}

Por favor, no borre este comentario

 0
Author: 122,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-10 05:35:57
    private void button1_Click(object sender, EventArgs e)
    {

        if (button2.Enabled == false)
        {
            timer1.Stop();
            button2.Enabled = true;
            label1.Text = "Preteklo je " + progressBar1.Value + " desetink";

        }
        else
        {
            timer1.Start();
            button1.Enabled = false;
            progressBar1.Value = 0;
            label1.Text = "";
        }
    }



    private void button2_Click(object sender, EventArgs e)
    {

        if (button1.Enabled == false)
        {
            timer1.Stop();
            button1.Enabled = true;
            label1.Text = "Preteklo je " + progressBar1.Value + " desetink";

        }
        else
        {
            timer1.Start();
            button2.Enabled = false;
            progressBar1.Value = 0;
            label1.Text = "";
        }


    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        if (progressBar1.Value < progressBar1.Maximum)
        {
            progressBar1.Value++;
            if (progressBar1.Value == progressBar1.Maximum)
            {
                timer1.Stop();
                button2.Enabled = true;
                button1.Enabled = true;
            }
        }

    }
}

}

 -1
Author: 122,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-10 05:50:36