How to prevent a backspace key stroke in a TextBox?
Asked Answered
N

8

6

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).)

Needlecraft answered 9/3, 2013 at 21:35 Comment(2)
Isn't there an event like "PreviewKeyDown"?Hurlburt
Silverlight for Windows Phone does not carry an implementation of PreviewKeyDown.Benzo
P
0

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;
    }
Pacifically answered 10/3, 2013 at 8:13 Comment(1)
The accepted solution is not the best. Better suggestion below using e.SuppressKeyPressTowroy
D
15

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).

Darrin answered 5/8, 2013 at 16:13 Comment(0)
B
3

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

Benzo answered 9/3, 2013 at 23:46 Comment(0)
J
1

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;
    }
Jariah answered 11/3, 2013 at 4:47 Comment(0)
P
0

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;
    }
Pacifically answered 10/3, 2013 at 8:13 Comment(1)
The accepted solution is not the best. Better suggestion below using e.SuppressKeyPressTowroy
S
0
    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;
        }
    }
Sahib answered 10/3, 2013 at 8:47 Comment(0)
R
0

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?)

Rebuttal answered 22/2, 2014 at 5:11 Comment(0)
F
0

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;
    }
}
Filemon answered 27/9, 2019 at 12:7 Comment(0)
M
0

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
        }
    }
Moersch answered 28/6, 2022 at 13:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.