-1

In a key pressed event I am using the code here to disable some keys (e.g. I want to allow typing only numbers). However, this also disable shortcuts like CTRL-C and so on. I can still copy and paste with the mouse, and I can still use those shorcuts in which I do not use my KeyPressEventHandler.

Here is the code I am using:

class IntegerTextBox : TextBox
{
    public IntegerTextBox()
    {
        KeyPress += new KeyPressEventHandler(accept_only_digits); //disable "wrong" key presses, https://stackoverflow.com/a/4285768/2436175
    }

    void accept_only_digits(object sender, KeyPressEventArgs e)
    {
        char ch = e.KeyChar;

        if (!char.IsNumber(ch) && ch != (char)Keys.Back && ch != (char)Keys.ControlKey) //The latter doesn't help
        {
            e.Handled = true;
            return;
        }

    }
}

However, the KeyPressEventArgs, differently from the KeyEventArgs, doesn't seem to have the information necessary to know if the ctrl key is pressed. Is there a way to circumvent this? For example something to prevent my KeyPressEventHandler to be called if the ctrl key is currently pressed?

Note 1: I am aware that in this way users will be allowed to paste also garbage
Note 2: I have also code to handle inserting negative numbers, but it's not relevant at this stage

Community
  • 1
  • 1
Antonio
  • 19,451
  • 13
  • 99
  • 197

2 Answers2

2

Change:

ch != (char)Keys.ControlKey. 

into:

!char.IsControl(ch)

This also makes superfluous your check for backspace.


By the way, I use a difference approach with my "only int textbox" with overriding pasted text guided from here.

    void TextBoxOnlyInt_KeyPress(object sender, KeyPressEventArgs e)
    {
        if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar) && (e.KeyChar != '-'))
        {
            e.Handled = true;
        }
        if (e.KeyChar == '-')
            if ((sender as TextBox).Text.Length != (sender as TextBox).SelectionLength)
                if ((sender as TextBox).Text.Length > 0)
                    e.Handled = true;
    }

    protected override void WndProc(ref Message m)
    {
        int i;
        if (m.Msg == 0x302)
            if (int.TryParse(Clipboard.GetText(), out i))
            {
                //some restrict to avoid pasted make textbox value become invalid
                if (i < 0 && this.SelectionStart != 0)
                    return;
                else if (i < 0 && this.Text[0] == '-')
                    return;
                else if (this.SelectionStart == 0 && this.Text[0] == '-')
                    return;
                else
                {
                    this.SelectedText = Clipboard.GetText();
                    return;
                }
            }
            else return;
        base.WndProc(ref m);
    }
Community
  • 1
  • 1
Nam Bình
  • 412
  • 2
  • 13
  • However this doesn't allow you to *copy* or *cut* from your box, does it? – Antonio Sep 22 '15 at 09:58
  • Nope, I just handle paste, which only allow past a valid integer value (this case i still need to check if textbox have a minus mark to disallow a negative integer). Everything else, copy, cut, select all... still function by default :) – Nam Bình Sep 23 '15 at 01:16
  • For me they don't work by default because I intercept keypress events as explained in the question. Apart what he is pasting, are you also checking what the user is typing? – Antonio Sep 23 '15 at 03:49
  • So I suppose the answer to my question lays in that `!char.IsControl(e.KeyChar)` in place of my `ch != (char)Keys.ControlKey`. All the rest is interesting but somehow out of scope. – Antonio Sep 23 '15 at 04:26
  • Thanks for the help! By the way, [here](http://chat.stackoverflow.com/transcript/message/25879932#25879932) is the code to use the minus sign to toggle positive/negative. – Antonio Sep 23 '15 at 08:02
  • You're welcome. btw, I already handled invalid minus sign input in `KeyPress`. But will give a try when I have time. Thanks :D – Nam Bình Sep 23 '15 at 08:06
0

Edit: See Nam Binh's solution, which is much simpler and to the point.


I solved by adding a KeyDown/KeyUp event handler, and saving the current status of the control key. It seems to work...

class IntegerTextBox : TextBox
{
    private bool controlDown;
    public IntegerTextBox()
    {
        controlDown = false;
        KeyPress += new KeyPressEventHandler(accept_only_digits); //disable "wrong" key presses, https://stackoverflow.com/a/4285768/2436175
        KeyDown += new KeyEventHandler(update_control_status);
        KeyUp += new KeyEventHandler(update_control_status);
    }

    void update_control_status(object sender, KeyEventArgs e)
    {
        controlDown = e.Control;
    }

    void accept_only_digits(object sender, KeyPressEventArgs e)
    {
        if (controlDown)
            {
            return;
            }

        char ch = e.KeyChar;
        //[...]
Community
  • 1
  • 1
Antonio
  • 19,451
  • 13
  • 99
  • 197