I have created a Window which has a ListView
to display a collection of persons. There are also 3 TextBox
es that are supposed to display person's first and last name, and an age. Finally, there's a Button
to save the new person data entered in those TextBox
es.
Loading persons into the ListView
is done by implementing MVVM. Works like a charm! Also, adding new people to the collection by clicking the Button
is also done through MVVM.
But there are two use cases that I am not sure whether it is wiser to use commands, i.e. MVVM, or just plain code-behind. The use cases are:
ListView
, the TextBox
es should show the person
details. TextBox
that displays
person's age, she or he should be warned that the entered data is incorrect. The reason why I am in doubt whether I should use MVVM or code-behind is because both use cases are related to view only (GUI), i.e. there is no interactivity with the model or application business logic. The ListView
item source is bound to a collection of persons ObservableColleciton<Person>
and all data related to the selected person is already passed to the view when the ListView
is populated with items. In the second use case, again, there is no need to go to ViewModel in order to let it fire the message box about the wrong user input. How about creating a validation callback in the age dependency property of the ViewModel class instead?
Thanks for all clarifications.
The single most important aspect of WPF that makes MVVM a great pattern to use is the data binding infrastructure. By binding properties of a view to a ViewModel, you get loose coupling between the two and entirely remove the need for writing code in a ViewModel that directly updates a view.
Code-behind is a term used to describe the code that is joined with markup-defined objects, when a XAML page is markup-compiled. This topic describes requirements for code-behind as well as an alternative inline code mechanism for code in XAML.
Both MVC and MVVM architectures contain a Controller piece. In fact, every software project has a Controller piece, since every software project manipulates data.
Let's have a look at a simple example in which we will be using MVVM approach. Step 1 − Create a new WPF Application project MVVMDemo. Step 2 − Add the three folders (Model, ViewModel, and Views) into your project. Step 4 − Add another StudentViewModel class into ViewModel folder and paste the following code.
The textboxes can and should definitely be populated through bindings in XAML when the ListView selection changes, eg:
<ListView Name="people" .../>
<TextBox Text="{Binding ElementName=people, Path=SelectedItem.FirstName}"/>
Or to reduce coding, put the text boxes in their own panel with a DataContext set, eg:
<Grid DataContext="{Binding ElementName=people, Path=SelectedItem}">
<TextBox Text="{Binding Path=FirstName}"/>
<TextBox Text="{Binding Path=LastName}"/>
</Grid>
Validation can be hooked-up in XAML, but the code that does the validating is typically implemented in a class. There's a convenient abstract class in System.Windows.Controls
called ValidationRule
that can be used to quickly create a validator. See this blog post for an example.
The only time I start dropping code into the code-behind files is when I cannot put it in the ViewModel or deeper in the object graph.
For example, you're first situation is, as mentioned above by C. Lawrence Wenham, completely solvable in XAML code. There is no need to resort to the code-behind to achieve this effect. And this example can be expanded to interactions with a collection that isn't necessarily presented in a control like a listbox. You can write XAML code the responds to changes in the current item in a collection in the ViewModel via binding.
Your second situation can also achieved through dvalidation facilities within the ViewModel and databinding to those facilities with your XAML. IDataErrorInfo is a great mechanism that is built in for just this purpose. Here is a nice little article demonstrating a simple use of IDataErrorInfo.
Examples of when you have to drop into code-behind are hopefully few and far between. One example I've encountered is when a control does not support ICommand and you can not bind functionality to a behavioral element, an example control being a ListBox. But there are some techniques to get around this limitation, as demonstrated in this great SO question. Also, in the event that you need to override rendering in custom controls, you'll need to do this in code-behind or in an inherited class.
Hope this adds a bit more useful information to the answers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With