2
votes

I have a TextBox control. After pressing space, I want, instead of whitespace, to put "|". This is my code:

void TextBox1KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
    if (e.KeyChar == (char)Keys.Space)
    {
        textBox1.AppendText("|");
    }
}

Problem is it doesn't write only "|", but "| ": After the pipe char, it puts a space and the cursor moves after that space. I tried to use this method:

textBox1.Text = textBox1.Text.Substring(0, (textBox1.TextLength - 1)); 

but it doesn't work because it deletes "|" instead of the space.

And another question is: I want to disable inserting " " when Space is pressed when textbox is empty. When u want to press space while textbox is empty, nothing happens, textbox will stay empty and cursor stay at the begining of textbox

i try this

void TextBox1KeyDown(object sender, KeyEventArgs e)
{

if (textBox1.Text.Length==0 && e.KeyCode == Keys.Space) {

          textBox1.Text=string.Empty;

  }

}

It doesnt work cause same reason like my previous question. That event is handled after " " is already added so textbox is not empty

PS: sorry for my english and thanks to whoever edit my post and fix my grammatical and spellig errors

4
Try to use onKeyReleasenbro
This question does not deserve down votes, in my modest opinion.nbro
@nbro: I agree, most developer learn with try-and-error the correct sequence of events of UI components.Willem Van Onsem

4 Answers

4
votes

Instead of KeyPress handle your requirement in the KeyDown event

void textBox1_KeyDown(object sender, KeyEventArgs e)
{
    if(e.KeyCode == Keys.Space && e.Modifiers ==  Keys.None)
    {
        e.SuppressKeyPress = true;
        textBox1.AppendText("|");
    }
}

As noted below from DrewMcGowen, this will add always the pipe at the end of the textbox text. If you move the cursor somewhere inside the current text the behavior of this approach is confusing and probably incorrect. This code instead tries to place the pipe exactly where the cursor is

void textBox1_KeyDown(object sender, KeyEventArgs e)
{
    if(e.KeyCode == Keys.Space && e.Modifiers ==  Keys.None)
    {
        e.SuppressKeyPress = true;
        int pos = textBox1.SelectionStart;
        textBox1.Text = textBox1.Text.Substring(0, pos) + "|" + textBox1.Text.Substring(pos);
        textBox1.SelectionStart = pos + 1;   
    }
}

Notice also that a check on the value of the Modifiers property of the KeyEventArgs parameter is mandatory. For example ALT+SPACE should activate the System Menu and not change your textbox in any way (see comment below from Mr HansPassant). Checking for Keys.None will avoid this logic also for CTRL and SHIFT modifiers, if you want these modifiers to be accounted for you need to change that check.

3
votes

The OnKeyPress event is fired before the space is added.

The workflow is thus:

  1. You press down [Space];
  2. The event is fired adding | to the content; and
  3. The space event itself is handled adding a space to the content.

You need to use KeyRelease or KeyUp...

1
votes

Documentation says:

Use the KeyChar property to sample keystrokes at run time and to modify keystrokes under special run-time circumstances. For example, you can use KeyChar to disable non-numeric keypresses when the user enters a ZIP code, change all alphabetical keypresses to uppercase in a data entry field, or monitor the keyboard or other key input device for specific key combinations.

So all you need is

if (e.KeyChar == ' ')
{
    e.KeyChar = '|';
}
1
votes

You forgot e.Handled = true; to suppress the space.

Monkeying with the user input is rather unwise. It is very disorienting and plain just doesn't work in some cases. Obvious failure modes are the user typing Ctrl+V or using right-click + Paste to insert text. Do this correctly with the Validating event:

    private void textBox1_Validating(object sender, CancelEventArgs e) {
        textBox1.Text = textBox1.Text.Replace(' ', '|');
    }

With high odds that you want to further improve this code by checking for two || next to each other or a leading or trailing |. You can set e.Cancel = true when you're unhappy, use ErrorProvider to give the user hints.