Luka967
Luka967

Reputation: 141

Custom RichTextBox OnKeyDown override doesn't work

I have this class inherited by RichTextBox. I overrided void OnKeyDown to check for incoming Tabs, because I don't want them.

Using breakpoints, I see that the overrided void is called, but it doesn't do its job.

Here is the code:

class ProgrammingTextBox : RichTextBox
{
    protected override void OnKeyDown(KeyEventArgs e)
    {
        if (e.KeyCode == Keys.Tab)
        {
            // Tab was pressed, replace it with space
            e.SuppressKeyPress = true; // Don't press Tab
            for (int i = 0; i < 4; i++)
            {
                base.OnKeyDown(new KeyEventArgs(Keys.Space); // Repeat space 4 times
            }
        }
        else base.OnKeyDown(e);
    }
}

The wanted output should be text with 4 spaces but results as a Tab, like the OnKeyDown call from the for loop wasn't called.

Any idea what should I do?

Upvotes: 2

Views: 335

Answers (2)

Hans Passant
Hans Passant

Reputation: 941357

    base.OnKeyDown(new KeyEventArgs(Keys.Space);

OnKeyDown() on OnKeyPress() only generates notifications, their job is not to modify the Text property. That's up to you, assign the SelectedText property. Like this:

class ProgrammingTextBox : RichTextBox {
    protected override bool IsInputKey(Keys keyData) {
        if (keyData == Keys.Tab) return true;
        return base.IsInputKey(keyData);
    }
    protected override void OnKeyDown(KeyEventArgs e) {
        if (e.KeyCode == Keys.Tab) {
            const string tabtospaces = "    ";
            var hassel = this.SelectionLength > 0;
            this.SelectedText = tabtospaces;
            if (!hassel) this.SelectionStart += tabtospaces.Length;
            e.SuppressKeyPress = true;
        }
        else base.OnKeyDown(e);
    }
}

Upvotes: 3

Dmitrii Bychenko
Dmitrii Bychenko

Reputation: 186668

When working with Tab (which is not an ordinary key - it can, say, be preprocessed and move focus control) you have to override a different method, ProcessCmdKey:

https://msdn.microsoft.com/en-us/library/system.windows.forms.control.processcmdkey(v=vs.110).aspx

Something like this

   protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
     if (keyData == Keys.Tab) {
       //TODO: Your code here

       return true;
     }

     return base.ProcessCmdKey(ref msg, keyData);
   }

see also

https://msdn.microsoft.com/en-us/library/system.windows.forms.textboxbase.acceptstab.aspx

Upvotes: 3

Related Questions