17

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 key strokes registered. Setting Handler to false here doesnt help and still i cant 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 overriden 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.

Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
whizzyifti
  • 259
  • 1
  • 2
  • 9
  • Since you are using `this.tbMessage.Text.Length` backspaces and delete will be reflected in the string `Text`. Or do you mean something else? – Stefan Oct 27 '11 at 14:31
  • 1
    why dont you use the [textchanged](http://msdn.microsoft.com/en-us/library/system.windows.controls.textbox.textchanged%28v=vs.95%29.aspx) event instead keydown? just count the content of the textbox everytime its changed – weberik Oct 27 '11 at 14:32
  • Thanks. TextChanged worked, after a little fiddling. – whizzyifti Nov 02 '11 at 04:55

3 Answers3

13

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;
        }
    }
}
Jamaxack
  • 2,400
  • 2
  • 24
  • 42
rockyashkumar
  • 1,302
  • 4
  • 13
  • 24
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;
    }
}
Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
DeltaPng
  • 505
  • 4
  • 6
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.

Marius
  • 9,208
  • 8
  • 50
  • 73
  • 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.cs – whizzyifti Nov 02 '11 at 05:01