Prevent user from typing certain char in TextBox - wpf

I am using WPF, MVVM-Light.
In my UI I have a textbox, and I want to prevent the user from typing certain characters in the textbox.
I know if we use code-behind I could handle the key down keyPress events, can I achieve it through MVVM?
Can we use some behaviors or some interactivity triggers?

Using code-behind is perfectly OK with MVVM providing the code-behind is related to your View only.
So if you have some view-specific logic that says "User can only type numbers in this box", then it's perfectly OK to write a KeyPress event for the TextBox that only allows numeric keys to be processed. You could even throw this into a UserControl so it can be reusable.
However if your allowed character logic is based on application logic, such as "User can only use the characters defined in the app.config file for this string value", then you'd be better off validating that in the ViewModel.
Also note that restriction is different from validation.
If you want to validate a user's entry, then I would do so using IDataErrorInfo from the ViewModel layer, and possibly a binding with a mode of UpdateSourceTrigger=PropertyChanged so the validation is checked after every key press.
If you want to restrict what characters can be typed into a TextBox, then I would probably do that from the View layer in the code behind, as that is a functionality of the View.

Yes, to filter input the MVVM way, I would suggest either using a custom control (such as a masked TextBox control) or a Behavior.
I was recently looking for a good masked TextBox and there is a free one out there from Xceed which you can find here. I can't speak to this one, as I haven't used it, but I've been happy with other Xceed components I've used in the past.
However I didn't want to go third party and include a bunch of controls I didn't need, so I ended up creating a behavior that simply attaches to the TextBox and filters the input based on a FilterType. The behavior is pretty easy to create, and you simply use the PreviewTextInput event to filter out characters that you don't want.
This SO Answer has a number of suggestions and links to how to filter/mask the input and if you're not familiar with creating Attached Behaviors, this example shows how to create an Attached Behavior for a Masked Text Box.

Related

WPF Numeric only TextBox - Handle it with event or command?

I am attempting to create a TextBox that only allows numeric characters and a decimal point. I don't need assistance in writing the code, but on the concept. I am using MVVM to design the WPF application and I'm not sure whether to use an event or event-to-command.
I have read several different viewpoints regarding this topic:
(I have found this to be a little extreme and as some have called it "counter-productive", but it upholds the "purity" of MVVM): Never have any code behind your View. To prevent this, use MVVM Light Library. In short, convert events to commands so that everything can be controlled in the ViewModel.
(The second argument does not uphold the (maybe over excessive) "purity" of MVVM): Not everything must be handled in the ViewModel and it is ok to create Events to handle certain UI requirements.
I was leaning more towards the second option because of simplicity and, as I have stated previously, the first option seems a little extreme. In my specific case (creating a numeric only TextBox) would most people prefer either of the above options or one I have not discovered?
You should handle this as an event in .cs file. You are trying to add functionality in a control. Like Text in a TextBox .They all are handeld in .cs file. ViewModel is resposible for holding the data and Behavior based on that Data for View not for the functionality of Control.
This should be handled directly in the View rather than involving the ViewModel, but there's no need to reinvent the wheel.
Depending on your exact numeric requirements, use a control such as DoubleUpDown or IntegerUpDown from the Extended WPF Toolkit (available via NUGet)

How to bind to application settings and be able to write unit tests when using the MVVM pattern?

I am trying to get started with the MVVM pattern and am struggling with this problem.
I have an input field where I enter the value for a search filter. I want to remember the value so, normally, I would save it in the application settings.
The input field is 2way bound to the settings in the View which works ok and doesn't create any application-dependencies in the ViewModel. This is important for unit testing, I think.
Now I would like to respond to changes in the input field and apply the filter but the binding is with the application settings and not the ViewModel.
How can I solve this problem? Can I 'double bind' a field - to the settings AND to the ViewModel? What is a sensible and pragmatic approach to this situation?
There are a couple of simple ways to deal with this, depending on your exact setup.
If you have just a textbox that the user types into and you filter the data in an interactive way, then you can use a TextChanged event handler in the code behind of the view*. From that event handler you can then invoke a command exposed by the viewmodel, that command can take the search text as its input and filter the data accordingly. Of course the viewmodel can also acceess your application settings data object, but I prefer the more immediate and declarative approach of having it as a parameter to the command.
If you have the textbox and then the search/filter is kicked off via a button, then you can just expose a command from the viewmodel which the button binds to, and as the command parameter you can use element binding to pass the text through to the command.
Using either of these methods your search/filter code in the viewmodel is very testable. You typically don't unit test code in the UI, so you don't need to worry about the code in the TextChanged handler. I should also mention that if you are using the interactive search then Reactive Extensions could be quite useful for you as they provide a convenient way to throttle the calls to the viewmodel.
*some people who consider themselves absolute purists would shudder at the thought of code in the view, but it's okay to do that provided it is purely UI/display related code, you can then call into the viewmodel via it's interface.

Which event should be used to update a Model from TextBox (LostFocus, LostKeyboardFocus, etc) in WPF? How to set precedence of events in WPF?

I have an application in which there are lot of TextBoxes and some Buttons like Save, SaveAs,etc.
When the user edits a TextBox, I have to check the DataBase for some range, validate the range and update the DataBase.
If there is any error in value entered by user,then I should not allow the TextBox to lose focus.
I was using LostFocus event for this and it was working fine until lately I discovered a bug in my application.
Bug : The user edits a value in TextBox and then clicks on Save button; the LostFocus event is not called and so Database is not getting updated :(
Now my question is which event should I use in TextBox to update the DataBase. I tried TextChanged event but it validates for every character and making my application slow. I am confused in chosing the right event for this kind of application!
Note :** The Buttons are in different UserControl !
EDIT 1 : I have some Commands attached to click of Buttons, these Commands are getting executed before LostFocus !! Can I set precedence or something like attached behaviours or commands should get executed after LostFocus !!
EDIT 2 : I was just debugging the application by disabling some commands, what I found was in some cases, the DelegateCommand gets executed before LostFocus, so I want to avoid that. How can I go about it ? I felt during development its impossible to developa pure MVVM application so I am kind of using a bit of codebehind !
Trapping the keyboard focus within a control is usually a sign of bad UI design - it's pretty user-hostile to force the user to fix data in a control before he can type anywhere else in the UI.
That said, you shouldn't be using events at all here. You're trying to write a Windows Forms application in WPF. You should write a WPF application.
Create a class that is a logical model of your view - i.e., there's a string property for the text box and a Command property (or, more likely, a RelayCommand) for the Save button. Bind the text box to the string property, e.g.:
<TextBox Text="{Binding MyTextProperty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
Because the UpdateSourceTrigger is PropertyChanged, the source object will get updated every time the user types a character.
Bind the button to the command property, e.g.:
<Button CommandBinding="{Binding SaveCommand}">Save</Button>
Implement the appropriate CanSave and Save methods that the RelayCommand (as described in Josh Smith's essential article on the MVVM pattern) requires, so that the button is enabled when the string property is valid and disabled when it's not.
I think the best approach is preventing a user to proceed until all valid information has been gathered.
Just like an installation wizard with Terms & Conditions Dialog and Next button. Until you check the I Agree checkbox, Next button is disabled.
This way, you don't have to worry about user proceeding without providing valid information. This way, you can use any event on TextBox to validate your data.

WPF Undo Redo Property System to highlight in red color if value has changed

I have a following requirement for a very complex UI. (Complex here means there are lot of controls in the form [approximately 100]). I am using MVVM (if my problem requires it to slightly go away from MVVM I am ok with it)
My question is for Editable ComboBox and TextBox. But I would say I like to hear a common algorithm which will fit all controls.
Requirement 1 : The user edits the content and goes to next control, the color of the control/text should become red.
Requirement 2 : When the user comes back to the previously edited control and enters the value which was initially present, the color of the control/text should become back to black.
I know the requirement is tough and I have been breaking my head to design a generic algorithm using which I can store the previous value and call a function to change the color of control.
To just give you all an idea, --> I tried storing 2 properties for every TextBox like Default_Text and Text. But since the number of properties are huge, the memory footprint is very huge. Also maintaining so many properties is very tough.
--> I tried adding a Dictionary to every ViewModel to store what values have got changed. But here the problem I faced was giving unique keys to all the controls in my application, which is not very helpful
--> I had even thought and tried about subclassing controls like TextBox, ComboBox and overriding some methods to suit my requirement, but sadly I failed miserabley when I started adding validations and all.
So here I am stuck with designing a generic WPF property system/algorithm to handle all undo redo functionality, changing styles of controls,etc!!!
It will be really great if you experts can guide me in right direction and also help me in developing such an algorithm/system. A sample illustration will be nice though!!!
I found an answer to the above problem. I used attached behavior for this. More details on this link Function call from XAML from StackOverFlow.
When I databind, I store the initial value of the DataBound variable in the Tag property by using Binding=OneWay. Then I have written a attached behaviour for LostFocus event. Whenever the user enters a control and then goes to other control, it fires LostFocus event and calls my attached behaviour. In this, I check whether the value is equal to the value in Tag. If it is same, I display in black else I display in red.
Attached Behaviour rocks in WPF. I can achieve anything from that cleanly without code cluttering!!!!
Another alternative is to use some "dirty" tracking in your models (or viewmodels) and bind to a properties isdirty (and convert it to a color).

How should I handle multiple events per control w/command pattern using MVVM in Silverlight?

Is anyone using the SLExtensions command pattern (http://www.codeplex.com/SLExtensions) for associating commands to Silverlight control events? From what I've seen, you can only attach a command for one event per control. For example, you can only add a click event for a button, a keydown event for a textbox, etc.
What if I wanted to add multiple events per control? For example, what if I wanted to add commands for both Click and Drop events for a button. Out of the box there does not seem to be a way to handle this with the SLExtensions code.
BTW, this is in a Model-View-ViewModel (MVVM) context.
Which events you wire upto in the XAML are a little limited, but but there's nothing to stop you doing it in the code behind/view model if it's not naturally supported by SLExtensions.
if (action == dropped)
{
Commands.Dropped.Execute();
else
{
Commands.Clicked.Execute();
}
Or whatever... if I've misunderstood you, some sample code of what you want to do would be helpful.
dwynne - You're absolutely correct. I could handle the drop event using the code you specified. However, I would still have to implement the event handler in my code-behind then call my ViewModel from there. I'm trying to adhere to MVVM by attempting the eliminate coding event handlers into my code-behind. Instead, I would like to wire-up my XAML to my ViewModel directly by using the attached commands.
The SLExtensions library allows you to do this but (from what I've experienced) only allows one event per control (Click for button, keydown for textbox, etc). For any non-trivial application this is not sufficient and your MVVM implementation breaks down.
Sorry for not using the comments area but 300 characters is a bit limiting. StackOverflow people - you need to up this limit.
I'm not familiar with SLExtensions but in WPF you have the same limit of one command per control, which is associated by the control implementation. If you want a command to execute for another event, you have to wire that yourself. However, there is a solution that doesn't require you to do this wiring in the code behind... attached behaviors. In fact, Caliburn (http://www.codeplex.com/caliburn) does just this with its "Action" concepts. I've not looked at Caliburn in a long time, and have no idea if it's Silverlight compatible, but you can certainly look into how the Actions are codified there and implement your own.

Resources