Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF: Where does MVVM stop and code-behind begins?

I have created a Window which has a ListView to display a collection of persons. There are also 3 TextBoxes 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 TextBoxes.

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:

  1. When user selects a person from the ListView, the TextBoxes should show the person details.
  2. When user types types characters instead of digits in the 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.

like image 453
Boris Avatar asked Apr 06 '11 20:04

Boris


People also ask

How does WPF MVVM work?

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.

What is code behind in WPF?

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.

Is there a controller in MVVM?

Both MVC and MVVM architectures contain a Controller piece. In fact, every software project has a Controller piece, since every software project manipulates data.

How do I start MVVM project?

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.


2 Answers

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.

like image 95
Chris Wenham Avatar answered Jan 03 '23 19:01

Chris Wenham


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.

like image 33
Dave White Avatar answered Jan 03 '23 21:01

Dave White