msbg
msbg

Reputation: 4962

How to prevent a backspace key stroke in a TextBox?

I want to suppress a key stroke in a TextBox. To suppress all keystrokes other than Backspace, I use the following:

    private void KeyBox_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
    {
        e.Handled = true;
    }

However, I only want to suppress keystrokes when the key pressed was Backspace. I use the following:

        if (e.Key == System.Windows.Input.Key.Back)
        {
            e.Handled = true;
        }

However, this does not work. The character behind the selection start is still deleted. I do get "TRUE" in the output, so the Back key is being recognized. How would I prevent the user from pressing backspace? (My reason for this is that I want to delete words instead of characters in some cases, and so I need to handle the back key press myself).)

Upvotes: 6

Views: 18161

Answers (8)

Julio Aguiar
Julio Aguiar

Reputation: 1

Just put this text in the KeyDown event of the textBox (Example: textBox18):

    private void textBox18_KeyDown(object sender, KeyEventArgs e)
    {
        e.SuppressKeyPress = true;      // cancels the typed character
        if (e.KeyValue != 8)            // checks if key typed is Backspace 
        {
            e.SuppressKeyPress = false; // if it is not Backspace then reactivates/enables the typed character
        }
    }

Upvotes: 0

Huy Nguyen
Huy Nguyen

Reputation: 928

Just set e.SuppressKeyPress = true (in KeyDown event) when you want to suppress a keystroke. Ex, prevent backspace key change your text in textbox using the following code:

private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
    if (e.KeyCode == Keys.Back)
    {
        e.SuppressKeyPress = true;
    }
}

Note that if you try this in the txtBox1_KeyUp() handler, it will not appear to work (because KeyDown already handled the event for the TextBox).

Upvotes: 15

salkow
salkow

Reputation: 29

This is an easy solution that works for me.

private void MyTxtbox_Keypress(object sender, KeyPressEventArgs e)
{
    if (e.KeyChar == '\b')
    {
        e.Handled = true;

        return;
    }
}

Upvotes: 0

CodeManX
CodeManX

Reputation: 11885

This is what I came up with to delete previous (CtrlBackspace) and next word (CtrlDelete), handling multiple subsequent whitespace characters (0x09, 0x20, 0xA0):

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace DeleteWord
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void textBox1_KeyDown(object sender, KeyEventArgs e)
        {
            // Tab, space, line feed
            char[] whitespace = {'\x09', '\x20', '\xA0'};
            string text = textBox1.Text;
            int start = textBox1.SelectionStart;

            if ((e.KeyCode == Keys.Back || e.KeyCode == Keys.Delete) && textBox1.SelectionLength > 0)
            {
                e.SuppressKeyPress = true;
                textBox1.Text = text.Substring(0, start) + text.Substring(start + textBox1.SelectionLength);
                textBox1.SelectionStart = start;
                return;
            }

            else if (e.KeyCode == Keys.Back && e.Control)
            {
                e.SuppressKeyPress = true;

                if (start == 0) return;

                int pos = Math.Max(text.LastIndexOfAny(whitespace, start - 1), 0);

                while (pos > 0)
                {
                    if (!whitespace.Contains(text[pos]))
                    {
                        pos++;
                        break;
                    }
                    pos--;
                }

                textBox1.Text = text.Substring(0, pos) + text.Substring(start);
                textBox1.SelectionStart = pos;
            }
            else if (e.KeyCode == Keys.Delete && e.Control)
            {
                e.SuppressKeyPress = true;

                int last = text.Length - 1;

                int pos = text.IndexOfAny(whitespace, start);
                if (pos == -1) pos = last + 1;

                while (pos <= last)
                {
                    if (!whitespace.Contains(text[pos])) break;
                    pos++;
                }

                textBox1.Text = text.Substring(0, start) + text.Substring(pos);
                textBox1.SelectionStart = start;
            }
        }

        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            if (keyData == Keys.Tab)
            {
                textBox1.Paste("\t");
                return true;
            }
            else if (keyData == (Keys.Shift | Keys.Tab))
            {
                textBox1.Paste("\xA0");
                return true;
            }
            return base.ProcessCmdKey(ref msg, keyData);
        }

    }
}

Thanks to Huy Nguyen for e.SuppressKeyPress = true;!

If there's a selection, both Delete and Backspace will delete the selection, regardless of modifier keys (you won't get that ugly rectangular character for holding Ctrl)

Seems to work for chars like 𤽜 as well, although it might not make much sense (isn't this character a whole word?)

Upvotes: 0

Jake Anderson
Jake Anderson

Reputation: 241

This requires that we store the value of the text box before the key down event. Unfortuantely the backspace is handled before that event is fired so we have to capture it before that takes place and then we can update it again after the key up event is procesed.

    private string textBeforeChange;

    private void TextBox1_OnKeyDown(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Back)
        {
            e.Handled = true;
            textBox1.Text = textBeforeChange;
        }
    }

    private void TextBox1_OnKeyUp(object sender, KeyEventArgs e)
    {
        textBeforeChange = textBox1.Text;
    }

    private void MainPage_OnLoaded(object sender, RoutedEventArgs e)
    {
        textBox1.AddHandler(TextBox.KeyDownEvent, new KeyEventHandler(TextBox1_OnKeyDown), true);
        textBox1.AddHandler(TextBox.KeyUpEvent, new KeyEventHandler(TextBox1_OnKeyUp), true);
        textBox1.AddHandler(TextBox.ManipulationStartedEvent, new EventHandler<ManipulationStartedEventArgs>(TextBox1_OnManipulationStarted), true);
    }

    private void TextBox1_OnManipulationStarted(object sender, ManipulationStartedEventArgs e)
    {
        textBeforeChange = textBox1.Text;
    }

Upvotes: 1

Hamzeh Soboh
Hamzeh Soboh

Reputation: 7710

    string oldText = "";
    private void testTextBlock_TextChanged(object sender, TextChangedEventArgs e)
    {
        if (testTextBlock.Text.Length < oldText.Length)
        {
            testTextBlock.Text = oldText;
            testTextBlock.SelectionStart = oldText.Length;
        }
        else
        {
            oldText = testTextBlock.Text;
        }
    }

Upvotes: 0

Rob.Kachmar
Rob.Kachmar

Reputation: 2188

It's true that there is no easy way to handle this scenario, but it is possible.

You need to create some member variables in the class to store the state of the input text, cursor position, and back key pressed status as we hop between the KeyDown, TextChanged, and KeyUp events.

The code should look something like this:

    string m_TextBeforeTheChange;
    int m_CursorPosition = 0;
    bool m_BackPressed = false;

    private void KeyBox_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
    {
        m_TextBeforeTheChange = KeyBox.Text;
        m_BackPressed = (e.Key.Equals(System.Windows.Input.Key.Back)) ? true : false;
    }

    private void KeyBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        if (m_BackPressed)
        {
            m_CursorPosition = KeyBox.SelectionStart;
            KeyBox.Text = m_TextBeforeTheChange;
        }
    }

    private void KeyBox_KeyUp(object sender, System.Windows.Input.KeyEventArgs e)
    {
        KeyBox.SelectionStart = (m_BackPressed) ? m_CursorPosition + 1 : KeyBox.SelectionStart;
    }

Upvotes: 0

Den
Den

Reputation: 16826

In Silverlight, there is no way to handle system key events, such as backspace. Therefore, you can detect it, but not handle it manually.

Upvotes: 3

Related Questions