[Expand]General Information
[Collapse]WinForms Controls
  .NET Core Support
 [Expand]What's Installed
 [Collapse]Build an Application
  [Expand]Choose Application UI
  [Expand]Printing and Exporting
  [Collapse]WinForms MVVM
   [Expand]Design-time Support
     Lesson 1 - Creating The Project. Scaffolding Wizard.
     Lesson 2 - Creating Views
     Lesson 3 - Navigation and Services
     Lesson 4 - Data Binding
     Lesson 5 - Login Form
     Lesson 6 - Lookup Editors and Master Detail
     Lesson 7 - Additional Functionality
  [Expand]Right-to-Left Layout
   Redistribution and Deployment
   How to: Perform Actions On Application Startup
 [Expand]Controls and Libraries
 [Expand]Common Features
  Get More Help
 [Expand]API Reference
[Expand]ASP.NET Controls and MVC Extensions
[Expand]ASP.NET Bootstrap Controls
[Expand]ASP.NET Core Bootstrap Controls
[Expand]WPF Controls
[Expand]Xamarin Controls
[Expand]Windows 10 App Controls
[Expand]Office File API
[Expand]Report and Dashboard Server
[Expand]eXpressApp Framework
[Expand]eXpress Persistent Objects
[Expand]CodeRush Classic
[Expand]Cross-Platform Core Libraries
[Expand]Tools and Utilities
 End-User Documentation
View this topic on docs.devexpress.com (Learn more)

Lesson 7 - Additional Functionality

There are endless minor improvements that can bring your sample application closer to a real-life application. In this section, you will learn how to implement several of them.

Expanded Double-click Editing

First, set the ColumnViewOptionsBehavior.Editable property for all your grid controls to false and add the following code to your detailed Views.

This will disable editing collection entities in the detailed Views. Instead, end-users will be able to double-click the desired record and make changes in the corresponding edit form (see the animation below).

Expanded Synchronizing Views

Consider the following example: your detail Views in the sample application display funds remaining on the selected account not in the detail View's grid, but in the separate editor (see the following figure). This task implies that you need to display data from the same data source within separate Views. Moreover, changes within one View must be reflected in another. In this case, you can use the Messenger to synchronize these Views.

The figure below illustrates this AccountsDetailView that hosts this editor.

This View displays info about the selected record only (a single entity) and thus, can be related to the already existing AccountViewModel. In this case, you can bind the editor's BindingSource component to the Entity object, generated by the Scaffolding Wizard.

What you need now is to update this binding when an end-user selects another grid row in the detail View. To do so, override the base OnSelectedEntityChanged method from the CollectionViewModel and send the new selected entity as a message.

Now you need to receive this message within your AccountViewModel - the View Model your AccountsDetailView View is using. The Layer Communication. Messenger topic states that once you use the Messenger.Default.Register method, the permanent channel that 'listens' for all incoming messages is opened. Thus, it is sufficient to call this method only once in the ViewModel's constructor.

When it is done, selecting a new row within the detail View will trigger sending the account, associated with this row, as a message. The AccountsDetailView will receive this entity as a message and extract the Amount field from it.

The OnSelectedAccountChangedMessage method listed in the code snippet above is a custom method and needs to be implemented manually. This method will be retrieve the required entity each time the message is received.

Expanded Modifying Default Confirmation Strings

The ViewModels generated by the Scaffolding Wizard already have several behaviors attached to your application. For instance, attempts to close the modified record without saving the changes will force the confirmation message to pop-up.

Double-click the CommonResources.resx file included in your solution to modify these confirmation texts and other strings used by default.

Expanded Adding Additional Confirmation Behaviors

You can extend the application by adding your own behaviors for certain events. For instance, the code snippet below illustrates the confirmation behavior attached to the form's FormClosing event (refer to the Behaviors topic to learn more).

Expanded Processing Multiple Entities Selection

In a real-life application, end-users should be able to select multiple entities at once. To do so, turn on multi-selection for your detailed Views' grid controls as shown below.

After that, you will need to update View command availability based on the number of currently selected grid rows. For instance, the 'Edit' command should obviously be disabled when multiple rows are selected simultaneously.

First, add the selected entities collection to the base CollectionViewModel and change the callback for this collection, which will raise each time selection is modified.

Then, you will need to populate this collection for each detailed View. For instance, for the Accounts View, the code will look like this.

Now, when the number of the currently selected rows is reflected by the Selection collection, modify the CanEdit function accordingly.

After this improvement, the 'Edit' command will be enabled only when one row is currently selected.

Expanded Removing Multiple Records At Once

After the previous improvement, you can easily update the Delete command. To do so, you can implement your own DeleteAll command.


The confirmation message code should be removed from the default Delete command implementation and pasted here to the DeleteAll command. Note that this code uses the CommonResources.Confirmation_DeleteAll text - you should create a corresponding entry in common resources, as was shown above.

As your Delete ribbon item is generated and bound to the related command automatically (see Lesson 2 - Creating Views), go to the View's designer code and bind this button to your new command.

As a result, you will be able to remove multiple entities at once by clicking the 'Delete' button.

Expanded Validating Values

The Lesson 4 - Data Binding tutorial explains how to validate edit form editors using Data Annotation Attributes and binding using the SetObjectDataSourceBinding method. In this section, you will implement validation for your login form. Let us go back to this form and see how it works.

You login ViewModel exposes public property for the current user only. Properties for user credentials (login and password) are defined in a separate class 'User'.

The login ViewModel also has the method that re-checks credentials, entered by an end-user.

Login form's editors are bound to corresponding fields of the Binding Source component with the userBindingSource name.

Finally, the Binding Source component is bound to the ViewModel's currentUser property by using the SetObjectDataSourceBinding method. This binding syntax specifies the Update method as the method that should be raised whenever the bound entity (current user) changes.

The usage of the SetObjectDataSourceBinding method makes it possible to validate end-user input by declaring required Data Annotation Attributes before properties, defined within the User class. The 'Password' editor should have no validation since user credentials are checked by the application itself. Ergo, the only editor appropriate for validating is the 'Login' editor. The code below uses the [Required] attribute to prohibit end-users from leaving this editor empty.

The result is shown on the following figure.

This is the scenario where you need to validate an individual entity (in this case - the current user). There also can be scenarios where the entire ViewModel has to be validated. This happens when validated properties are defined within the ViewModel itself and this ViewModel should be set as the data source for the Binding Source component. In this case, you can use the shortened binding syntax, as shown below.

Note that in both cases, validation works not because you have used the SetObjectDataSourceBinding method, but because DevExpress editors used within your Views support validation. The SetObjectDataSourceBinding method simply allows these editors to retrieve Data Annotation Attributes and promptly react to end-user input.

Expanded Complete Sample

Follow this link to download the final application.

Is this topic helpful?​​​​​​​