Detection of Backspace on KeyDown
Asked Answered
W

3

19

I am working on a Silverlight web app. It interacts with a module that sends SMS's. I want to limit the text to 160 and show a counter. I did it like this:

public partial class SendSMSView
{
    public SendSMSView()
    {
       InitializeComponent();
       ApplyTheme();
    }

    protected void tbMessage_KeyDown(object sender, KeyEventArgs e)
    {
        count = 160 - this.tbMessage.Text.Length;
        this.lblCount.Content = count.ToString();
    }
}

This works fine for all the keys except backspace and delete. Of course, it is made to function like this. I dug more on this and tried overriding KeyDown event. So, I added the following code snippet:

public class CustomTextBox : TextBox
{
    public CustomTextBox(): base()
    {
    }

    protected override void OnKeyDown(KeyEventArgs e)
    {
        e.handler=false;
        base.OnKeyDown(e);
        //this place
    }
}

In OnKeyDown function, I get all the keystrokes registered. Setting Handler to false here doesn't help and still I can't get backspace to trigger tbMessage_KeyDow.

I want to somehow call the tbMessage_KeyDow function from //this place forcefully from there for backspace.

I searched MSDN and found that IsInputKey can be overridden to return true so that OnKeyDown responds to it as well, but My framework neither has IsInputKey nor PreviewKeyPress. Is there a workaround for getting backspace key registered as input key, or to call tbMessage_KeyDow [which is very crude approach]? Please help!

Wilbanks answered 27/10, 2011 at 14:25 Comment(3)
Since you are using this.tbMessage.Text.Length backspaces and delete will be reflected in the string Text. Or do you mean something else?Downwash
why dont you use the textchanged event instead keydown? just count the content of the textbox everytime its changedChile
Thanks. TextChanged worked, after a little fiddling.Wilbanks
K
16

try this ....

If you want to detect the backspace key on the key pressed in a textbox. we would suggest that you can try to do in the textbox's KeyUp event instead of the KeyDown event. for example:

   <TextBox x:Name="txt" KeyDown="txt_KeyDown" Text="Hello" KeyUp="txt_KeyUp"></TextBox>    

the codebehind:

    private void txt_KeyUp(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Back)
        {
            MessageBox.Show(this.txt.Text);
        }
    } 

or you can do like this...by creating a user control....

public partial class Page : UserControl {

    private TextBox TextBox1;

    public Page() {
        InitializeComponent();
        TextBox1 = new TextBox();
        Width = 300;
        Height = 100;
        LayoutRoot.Children.Add(textbox);
        OnTextChanged(((object)(sender)), ((TextChangedEventArgs)(e)));
        TextBox1.TextChanged;
        if (e.Key == Key.Back) {
            e.Handled = true;
        }
        else if (e.Key == Key.Delete) {
            e.Handled = true;
        }
    }
}
Korwin answered 27/10, 2011 at 14:36 Comment(0)
F
4

I was looking for something similar for a WPF application, Backspace and Delete keys were not being caught by the KeyDown event. The KeyUp event was not workable, bc it would catch the keypress AFTER the action had already occurred.

Found however, that PreviewKeyDown event worked to capture the keypress, so that I could prevent the keypress from occurring, like so:

private void txtRight_PreviewKeyDown(object sender, KeyEventArgs e)
{
    if ((e.Key == Key.Delete) || (e.Key == Key.Back))
    {
        // Stop the character from being entered into the control since it is illegal.
        e.Handled = true;
    }
}
Footy answered 9/6, 2018 at 0:34 Comment(0)
C
0

I would do something like this (I don't have VS in front of me so this is pure pseduo code)

public class SendSMSViewModel : INotifyPropertyChanged
{
   string _text;

   public string Text 
   { 
      get { return _text; }
      set {

          // or allow it and implement IDataErrorInfo to give the user a nifty error message          
          if (value != null & value.Length > 160)
              return;

          _text = value;
          OnPropertyChanged(vm => vm.Text);
          OnPropertyChanged(vm => vm.NumberOfCharactersRemaining);
     }
   }

   public string NumberOfCharactersRemaining 
   { 
       get { return Text == null ? 160 : 160 - Text.Length; }
   }
}

..and then use two way databinding from your view and remember to use an UpdateSourceTrigger of "PropertyChanged" on your bindings.

Carpetbagger answered 27/10, 2011 at 18:42 Comment(1)
Thanks, The ViewModel Implementation works, infact i have done it many times before. I was trying to avoid extra code working it out in the View.csWilbanks

© 2022 - 2024 — McMap. All rights reserved.