TimB
TimB

Reputation: 1000

Cannot handle Ctrl + S in RichTextBox

I'm coding a text editor for part of my winforms application. It has the usual Bold, Underline, Strikeout, Italic toolbar buttons. For reasons of accessibility and workflow efficiency I want to add shortcuts as well, however.

Here's the relevant code:

private void TextInput_KeyDown(object sender, KeyEventArgs e)
{
    if(e.Control)
    {
        switch(e.KeyCode)
        {
            case Keys.B: ChangeFontStyle('B');
            break;
            case Keys.I: e.SuppressKeypress = true; 
            ChangeFontStyle('I');
            break;
            // ... the others (U and S) look like the one for B, with the matching letters... 
        }
        }
    }
}

private voide ChangeFontStyle(char targetStyle)
{
    switch(targetStyle)
    {
        case 'B': 
        if(TextInput.Selectionfont.Bold)
        { 
            TextInput.SelectionFont = new Font(TextInput.Selectionfont, TextInput.Selectionfont.Style ^ FontStyle.Bold);

        }
        else
        {
           TextInput.SelectionFont = new Font(TextInput.Selectionfont, TextInput.SelectionFont.Style | FontStyle.Bold);
        }
    }
}

The others look like this, too, just with italic, underline and strikeout respectively. For three of them itorks (though if I don't " e.SuppressKeyPress on ctrl-I, an indent gets set on top of font turning italic). Just strikeout doesn't work with ctrl-S. With ctrl-shift-S it works, and the case 'S' block never executes, so ctrl-S must somehow get caught somewhere and used for something else. But I definitely don't use it elsewhere. Suggestions?

Upvotes: 4

Views: 791

Answers (1)

Reza Aghaei
Reza Aghaei

Reputation: 125207

When you have a MenuStrip on the form including a menu item with Ctrl + S as ShortcutKey, then Ctrl + S will be consumed by menu item and your control will not receive the key combination.

KeyDown event of RichTextBox is too late for handling shortcut keys and MenuStrip or parent controls may consume the key combination in their ProcessCmdKey.

To handle shortcut keys for RichTextBox, use one of the following options:

  • Have a MenuStrip including a ToolStripMenuItem assigned with the shortcut key to its ShortcutKeys propert, then handling Click event of the menu item:

    private void saveToolStripMenuItem_Click(object sender, EventArgs e)
    {
        MessageBox.Show("Handled by Save Menu");
    }
    
  • Override ProcessCmdKey method of the Form:

    protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {
        if (keyData == (Keys.Control | Keys.S))
        {
            MessageBox.Show("Handled by Form");
            return true;
        }
        return base.ProcessCmdKey(ref msg, keyData);
    }
    
  • The last option is using PreviewKeyDown event of the RichTextBox:

    private void richTextBox1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
    {
        if (e.KeyData == (Keys.Control | Keys.S))
        {
            e.IsInputKey = true;
            BeginInvoke(new Action(() => {
                MessageBox.Show("Handled by RichTextBox");
            }));
        }
    }
    

Upvotes: 4

Related Questions