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)
Related
I've seen many data binding frameworks, such as WPF, AngularJS(Javascript), JSTL(JSP).
They are trying to separate UI and Data completely.
However, one main problem is that it adds complexity. Sometime, you have to write a lot of extra code (for example to extend a view class) just for one line of UI code.
In modern applications, there are many transition animations when changing one UI element from one state to another state. When use data binding framework, it seems not easy.
Are there any other cons of using a data binding framework?
For example, to set focus on a text input, so complex in AngularJS, See:
How to set focus on input field?
All of the following refers to the WPF.
You have to write a lot of extra code (for example to extend a view class) just for one line of UI code.
With regard to the WPF, this is rare situation, you can give an example?
There are many transition animations when changing one UI element from one state to another state.
In WPF since version .NET 3.5 appeared VisualStateManager:
The VisualStateManager enables you to specify states for a control, the appearance of a control when it is in a certain state, and when a control changes states.
His goal - is to define the application state, and each state to do an action, such as an animation. In this situation Binding is not used as such.
When use data binding framework, it seems not easy.
I do not think it's disadvantage. Data Binding needed as you mentioned: separate UI and Data completely. In fact, the whole MVVM pattern is based on a powerful technology as Data Binding. This feature allows you to create an abstract connection between Model and View via ViewModel. And the key word is Data, everywhere where there is work with the data, it is better to use Data Binding.
Binding allows you to do many interesting things, such as Validation, Converters and much more. It is typically used for Binding properties, and nothing more. To work with the UI using other features like VisualStateManager, Triggers, DataTriggers, etc. and it is not difficult when you use it to its destination, just need to get used to.
The only downside - is that Binding can be used for other purposes, such as use of the Converter when you can not do without it. And yes, at first it may seem unusual, but I do not think that this a drawback, the same can be said about other technologies.
Even as a drawback can be said about the performance. If you assign a value directly or via Binding, assigning a value directly will be faster. But I think that the advantages of Bindings allow not pay much attention to it.
My MVVM program is a media player and uses the Media Element's Natural Duration property to set the Media Timeline's duration. Before I implemented MVVM design pattern, I could simply put
MyMediaTimeline.Duration = MyMediaElement.NaturalDuration;
in the code-behind. I am new to using MVVM but I believe this is not the correct way to perform this action according to the MVVM design pattern. I believe that MediaElement.NaturalDuration is not a dependency property so it cannot be bound to directly. Do I need to make it a dependency property somehow? Would this be coded in the ViewModel?
When we need to implement functionality like this that relates to UI controls using MVVM, we have a few options. One is to implement some kind of service or manager class that can implement this functionality for us and another is to use Attached Properties. Out of these two options, I believe this second option to be more suitable for this problem.
However, there is absolutely nothing wrong with adding event handlers into the code behind of your view, even when using MVVM. I keep seeing new users panicking over what to do rather than use the code behind when using MVVM. This is a common misconception about MVVM.
If you really know how to use Attached Properties properly, then I would advise that you use one (or more) of those to solve your problem, otherwise I would happily advise you to use the code behind. Note that if your view models are correctly data bound to your views, then you can access your view model from the code behind like this:
TypeOfViewModel viewModel = (TypeOfViewModel)DataContext;
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.
I am a newbie to WPF, and am trying to learn the standard idioms. I have a user control that allows the user to enter a mailing address, composed of six text boxes. I have also defined an interface IMailAddress, and a concrete class MailAddress that is a set of properties for the standard mail address fields. (US only for the moment.)
I figure by having an interface it means I could have some database class that holds everything about a person but implements this interface for the specific needs of this control.
What is the idiomatic way to tie this type into the control? I can certainly implement it as a dependency property, but does that make any sense with a type like this? Would I be better making it a standard property, and then raising a routed event when the value changed?
I'm not so much concerned about this specific example, but more generally what is considered best practice for these types of scenario.
Having your user control expose an IMailAddress property as a dependency property is perfectly valid. WPF itself does similar things; for example, ItemsControl expects you to bind a collection to it, so it exposes an ItemsSource dependency property of type IEnumerable.
User controls/custom controls are a good way to represent views, and don't let the MVVM freakazoids tell you otherwise :) Besides, there's no reason this can't work perfectly fine with MVVM - for example:
<local:MailAddressEditor
MailAddress="{Binding Path=Customer.BillingAddress}"
/>
One thing you may like to look at, though, is using a Custom Control instead of a UserControl. This will allow you to build a 'lookless' control that focuses on the logic behind editing an address, and allow users of your control to create Styles independently for rendering the control. When people use your control, they might use:
<local:MailAddressEditor
MailAddress="{Binding Path=Customer.BillingAddress}"
Style="{StaticResource SimpleInlineAddressEditor}"
/>
<local:MailAddressEditor
MailAddress="{Binding Path=Customer.BillingAddress}"
Style="{StaticResource ComplicatedAddressEditorWithGoogleMapsSelector}"
/>
In this case, we have one control, with two styles (and probably two ControlTemplates) to give the fields a different layout.
Custom controls are a great asset to a WPF developer - not everything has to be done via MVVM. Just try to stay conscious of the kind of code going into your custom control - if it's getting a little too logic-y, you might want to move some of that into a view model.
DependencyProperties are sort of fading away as INotifyPropertChanged is taking over with MVVM patterns. You should look at MVVM toolkits if you want to start using proper separation between your interface, data access, and business logic. You can still use DependencyProperties, but I would recommend you build a ViewModel to implement your interactions with your user control. One of the goals of MVVM is making testability easier by providing a ViewModel that can be verifed with unit tests outside of XAML-land.
A great starter MVVM toolkit for WPF is MVVM Light. A heavier weight MVVM toolkit would be Prism.
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.