0

I am having a go with RxUI within a WinRt project and just seeing if i can get something to work, i suspect that what i am doing is not a valid use case but thought i would ask to be sure.

I have a textbox that is bound to a property, i want to subscribe to the keydown event and prevent the user from inputting inappropriate characters (in this case, anything that is not a number). Due to using MVVM i do not have access to the textbox itself, only the binding values.

Can this still be done? - it seems a little odd to subscribe to property changed and then undoing their input afterwards, if it is undesirable.

4imble
  • 13,979
  • 15
  • 70
  • 125
  • 1
    I don't know if RxUI has support for this, but it sounds like you want to control key presses in your view model. This sounds more like interaction logic that you would encapsulate in a control or attached behavior and only have your view model provide accepted text format to the interactive code. – Filip Skakun Sep 05 '12 at 16:41

2 Answers2

4

This seems to be a UI based concern, so a more loosely-coupled approach would be to write a behavior class (basically an attached property which binds events), and attach it to the textbox in concern.

This way you can actively filter input and not have code-behind specific to that text-box.

Possible representation:

             <TextBox Text="{Binding...}"> 
               <Interaction:Interaction.Behaviors> 
                 <NumericTextBoxBehavior /> 
               </Interaction:Interaction.Behaviors> 
             </TextBox>

Have a look at:

Asti
  • 12,447
  • 29
  • 38
  • This is the way i went, as i was already using some "behaviors". Works quite nicely... thanks. – 4imble Sep 06 '12 at 08:59
2

Just because you're using MVVM, it doesn't mean that you can't put code in the View Code-Behind. In this case, I'd just do the simplest thing:

theTextBox.PreviewKeyUp += (o,e) => {
    if (!IsValidKey(e.Key))  e.Handled = true;
};

If you don't care for that, you can also filter it in the ViewModel after the fact, which may cause caret problems but is more testable:

this.WhenAny(x => x.SomeProp, x => x.Value)
    .Select(x => new { Filtered = FilterAllInvalidChars(x), Original = x} )
    .Where(x => x.Filtered != x.Original)
    .Subscribe(x => SomeProp = x.Filtered);
Ana Betts
  • 73,868
  • 16
  • 141
  • 209