Sorensen & Mihailesc WVVM Pattern
Sorensen & Mihailesc WVVM Pattern
1
Department of Computer Engineering
University of Southern Denmark, The Maersk Mc-Kinney Moller Institute
Campusvej 55, DK-5230 Odense M, Denmark
2
Department of Computer Science,
Titu Maiorescu University, Faculty Science and Information Technology,
Str. Dambovnicului, nr. 22, sector 4, 040441 Bucuresti, Romania, E-Mail: [email protected]
Abstract: Information society has and will involve electronic information and dependence computer networks. The
program includes a substantial proportion of resources which are allocated to information and communication activities.
Globalization digital consequently, the priority of the Internet, is a phenomenon inevitably, specific information for society.
In this whirlwind are attracted education systems which are beginning to adapt and to transform the electronic versions,
marking transition from traditional to digital age in which earning is approached as a process that takes place during the life
cycle through interactive learning environments. In the present communication, explores how use of computers beyond the
traditional form of IAC (most frequently encountered form of drill & practice).
1. INTRODUCTION
Since people began to create user interfaces for software were popular design patterns to help make it easier. For
example, the Model-View-Presenter pattern (MVP), has gained popularity in different programming platforms IU. MVP is a
variant of the Model-View-Controller pattern (MVP), which has been around for decades. In case you have never used
before MVP model, here is a simplified explanation. What you see on screen is the view, which displays the data is a model
and presenter joins the two together. View relies on a presenter to populate the data model, react to user input, ensure input
validation (perhaps by delegating to the model), and other such tasks.
2. WHY MVVM ?
Once a developer is comfortable with WPF and MVVM may be difficult to differentiate the two. MVVM is the lingua
franca of WPF developers, the platform that is well adapted to WPF, and WPF was designed to make it easier to build
applications using MVVM model (among others). In fact, Microsoft has used internally MVVM to develop WPF
applications such as Microsoft Expression Blend, while WPF was the basic core design. Many aspects of WPF, such as the
look of control and data model templates, use powerful separation of state and behavior display MVVM promoted.
Two other features of the WPF technology that make these models are patterns of data and system resources. Templates
for data visualization applied to objects ViewModel presented user interface. Being able to declare templates in XAML and
leaving reurse system automatically locate acetic sis patterns for you to apply on time.
If children were not only WPF support orders, MVVM model would be much less powerful. In this project we show
how one can expose VIewModel commands a view to allowing the use of its functionality.
In addition to the features of WPF (and Silverlight) MVVM forming a natural way to structure an application, the
model is also popular because VIewModel classes are easy to test drive. When an interaction logic applications, a set of
classes traieste''intr ViewModel, you can easily write code to test. In a sense, View and test sites are joined two other
different types of consumers ViewModels. Having a test suite for an application based on free and ViewModel providing a
rapid regression tests, helps reduce application maintenance costs over time.
In addition to promoting creearii automated regression tests, classes testabilitatea ViewModel properly can help in
designing user interfaces. When you design an application, you can often decide whether something should be in terms of
site ViewModel by imagining that you write a unit test without creating other object ViewModel IU.
In the end, for developers who work with visual designs using MVVM is much easier to create a sleek designer /
developer workflow for. The intention is only consumed by a ViewModel arbitrary, it is easy to 'break''a way to set a new
visuality sis make ViewModel vision. This simple step allows for rapid prototyping and evaluation of user interfaces made
by designers.
2
Development team can focus on creating robust ViewModel classes, and design team can be concentrated to make user-
friendly views. Connecting two outputs of teams that may involve little more than ensuring that proper linkages exist in
view of how a XAML file.
3
3. PRACTICAL MODEL-VIEW-VIEWMODEL DESIGN PATTERN ON APPPLICATION USING
WINDOWS PRESENATATION FOUNDATION (WPF)
Application is presented within this paper uses MVVM in several ways. It provides a fertile source of examples in
order to put the concepts into an understandable context. I created this application for a company using Visual Studio 2008
SP1, Microsoft. NET Framework 3.5 SP1.
Application can contain any number of 'work spaces''utiliatorul can open by clicking the blue link (see Figure 2) in
the left navigation section. All work spaces are in the TabControl's main window. The user can close the workspace by
clicking the Close button in the tab workspace. The application has two workspaces available: "All Customers" and "New
Customer." After running the application and opening workspaces, windows (IU) as shown in Figure 2.
Figure 2. Workspaces
Only one instance of the workspace, all clients can be opened in a single moment, but any number of workspaces New
user can be opened again. After completing the registration form data with valid values and clicking the Save button, new
customer name will appear on the View tab customer. The application has support for deleting or editing an existing
customer, but this functionality as well as many other similar features, are easy to create, based on top of existing
application architecture. Now we have a high level of understanding of what application can do, let invetigam way it was
designed and implemented.
4
In this application, class RelayCommand solve this problem. RelayCommand allow you to 'inject' control logic via
the constructor or the last delegation. RelayCommand DelegateCommand is a simplified version of what is found in
Microsoft Application Composite library. RelayCommand class is shown in your code snippet below:
#endregion // Campuri
#region Constructors
/// <summary>
/// Crearea unei comeni (command) care se poate executa oricand.
/// </summary>
/// <param name="execute">Executia logica (vezi documentatie)param>
public RelayCommand(Action<object> execute)
: this(execute, null)
{
}
/// <summary>
/// Crearea unei noi comenzi (command)
/// </summary>
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute;
_canExecute = canExecute;
}
#endregion // Constructorii
[DebuggerStepThrough]
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
5
_execute(parameter);
}
#endregion // Membrii interfetei ICommand
}
CanExecuteChanged event, which is part of implementing ICommand interface, has some interesting features. He
creates a delegate to CommandManager.RequerySuggested. This infrastructure ensures that all objects RelayCmmand
solitcita WPF control, in which case they can execute commands whenever require built-in type. Class
CustomerViewModel following code, which we will examine later, shows how to configure a RelayCommand using lambda
expressions:
RelayCommand _saveCommand;
public ICommand SaveCommand
{
get
{
if (_saveCommand == null)
{
_saveCommand = new RelayCommand(
param => this.Save(),
param => this.CanSave
);
}
return _saveCommand;
}
}
6
Figure 3. Inheritance Ierarchy
Having a base class for ViewModels not a necessity. If you prefer to obtain positions of your classes through the
formation of several smaller classes together, instead of using the principle of inheritance, there is no problem. Like any
other model design, MVVM is a set of guidelines, not rules.
7
feature can be a huge saving of time. ViewModelBase code that adds this support helpful is presented in the following
listing:
base.DisplayName = displayName;
this.Command = command;
}
8
In the file there is a DataTemplate MainWindowResources.xaml identified key 'CommandsTemplate.''
MainWindow uses this template to render CommandViewModels collection mentioned earlier. Simple template
CommandViewModel renders each object as a link in an ItemsControl. Each proprietary HyperlinkCommand is assigned to
the Command property of a CommandViewModel. The following XAML code shown in the following listing:
MainWindow menu contains an item whose type is assigned propietatii proprietary Command CloseCommand of
MainWindowViewModel. Can the user clicks that menu item, App class responds by calling Close window method, as
follows:
<Menu KeyboardNavigation.TabNavigation="Cycle">
<MenuItem Header="_File">
<MenuItem Header="E_xit" Command="{Binding Path=CloseCommand}" />
</MenuItem>
<MenuItem Header="_Edit" />
<MenuItem Header="_Options" />
<MenuItem Header="_Help" />
</Menu>
<DataTemplate x:Key="WorkspacesTemplate">
<TabControl
IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding}"
ItemTemplate="{StaticResource ClosableTabItemTemplate}"
Margin="4"/>
</DataTemplate>
When a user clicks the Close button in an item-type tab, then WorkspaceViewModel CloseCommand run, causing
the launch event or RequestClose. MainWindowViewModel RequestClose event monitor desktop and delete the workspace
Workspaces collection until the next request. Since when has the property of ItemsSource MainWindowTabControl
attributed to observable WorkspaceViewModels collection, removing an item from the collection causes the workspace to
be deleted from TabControl correspondent. This logic is shown in the following listing MainWindowViewModel:
10
{
if (e.NewItems != null && e.NewItems.Count != 0)
foreach (WorkspaceViewModel workspace in e.NewItems)
workspace.RequestClose += this.OnWorkspaceRequestClose;
The project UnitTest, MainWindowViewModelTests.cs file contains a test method that check that this function
works correctly. The ease with which you can create unit tests for classes ViewModel is a strength for MVVM pattern
because it allows for simple testing of application functionality without writing code that reaches''IU. This method is shown
in the following listing:
11
3.6. Apply an View to ViewModel
MainWindowViewModel indirectly add and delete items to TabControl WorkspaceViewModel the main window.
Based on data binding, the Content property of a derived object ViewModelBase Tabita receives a display. ViewModelBase
is not an IU, the conclusion has no support for rendering to legacy itself. By default, a non-visual object is rendered by WPF
afiarea results of a call to the ToString method in a TextBlock. In conclusion, this is not what we want, only if users have a
burning desire to see the type of classes ViewModel name.
In a very simple way to say how WPF's rendering an object using DataTemplates ViewModel sites. A
DataTemplate has a value x: Key assigned to him. If WPF is trying to rendering one ViewModel objects, it will check if the
system resources in order to have a DataTemplate type in which datatype is the same object type ViewModel. If you find
one, he will use the template to render the object referenced by ViewModel propietatii Content tab.
It has a ResourceDictionary MainWindowResources.xaml. This dictionary is added to the hierarchy of resources to
the main window, which means that the resources they contain are in order resource box. When a content of a tab is set to an
object ViewModel a DataTemplate of this dictionary provides a view (which is a user control) was used for rendering, as the
following listing:
<!--
This template applies an AllCustomersView to an instance
of the AllCustomersViewModel class shown in the main window.
-->
<DataTemplate DataType="{x:Type vm:AllCustomersViewModel}">
<vw:AllCustomersView />
</DataTemplate>
<!--
This template applies a CustomerView to an instance
of the CustomerViewModel class shown in the main window.
-->
<DataTemplate DataType="{x:Type vm:CustomerViewModel}">
<vw:CustomerView />
</DataTemplate>
No need to write any code to determine which view should be shown for one object ViewModel. WPF system's
resources do all the heavy stuff for you so you can concentrated on more important things. In more complex scenarios, it is
possible to programmatically select your view, but in most situations it is necessary only.
12
Single class model within this application is the Customer. This class has a set of properties that is helpful
information on a company's customer as name, address and email. It also provides message validation by implementing
IDataErrorInfo interface that existed years before WPF to hit the market. Customer class has nothing in it that shows that
architecture is used in WPF application. Class can also be as good a legacy of a business library.
Data should come and go somewhere. In this application, an instance of class load and keeps all objects
CustomerRepository Customer. It happens to upload customer data (customer) from an XML file, but the type of external
data sources is irrelevant. Data can also come from a BAA data, web service, a file on disk. As long as there is an object.
NET with some data in it, considering the place whence MVVM pattern can display data on screen.
CustomerRepository class provides several methods that allow to take over all the objects Customer, Customer to
add a repository, and check if a customer already exists in the repository. Since the application does not allow the user to
delete a client repository does not allow to delete a customer. CustomerAdded event is launched when a new client enters
CustomerRepository through AddCustomer method.
A clearer definition of the application data model is very small compared with actual business application
requirements, but this is important. What is important to understand is how the classes Customer and CustomerRepository
ViewModel use. Note that is wrapped around the object CustomerViewModel Customer. It exposes a client state, and other
states used to control CustomerView through a set of properties. CustomerViewModel not duplicate a client state, is simply
exposed via delegation as well:
_customer.FirstName = value;
base.OnPropertyChanged("FirstName");
}
}
13
When a user creates a new customer and click the Save button in the control CustomerView, CustomerViewModel
associated with that view it will add new Client object CustomerRepository. This causes the event to be launched
CustomerAdded that AllCustomersViewModel let know that you should add a new collection CustomerViewModel to
AllCustomers. In a sense, acting as a mechanism CustomerRepository synchronized between various models of type
ViewModels dealing with Customer objects. At a mere appearance he presents as Mediator pattern. I go back on it and how
they work on these sections to come, but now we resume the following diagram for a high-level understanding of how all
the parts are integrated.
target.CustomerType =
Strings.CustomerViewModel_CustomerTypeOption_Company;
Assert.IsTrue(cust.IsCompany, "Should be a company");
target.CustomerType =
Strings.CustomerViewModel_CustomerTypeOption_Person;
Assert.IsFalse(cust.IsCompany, "Should be a person");
target.CustomerType =
Strings.CustomerViewModel_CustomerTypeOption_NotSpecified;
string error = (target as IDataErrorInfo)["CustomerType"];
14
Assert.IsFalse(String.IsNullOrEmpty(error), "Error message should be
returned");
}
_customerType = value;
if (_customerType ==
Strings.CustomerViewModel_CustomerTypeOption_Company)
{
_customer.IsCompany = true;
}
else if (_customerType ==
Strings.CustomerViewModel_CustomerTypeOption_Person)
{
_customer.IsCompany = false;
}
base.OnPropertyChanged("CustomerType");
base.OnPropertyChanged("LastName");
}
CustomerView ComboBox control contains a box which is attributed to these properties, as in:
<ComboBox
x:Name="customerTypeCmb"
Grid.Row="0" Grid.Column="2"
ItemsSource="{Binding Path=CustomerTypeOptions, Mode=OneTime}"
15
SelectedItem="{Binding Path=CustomerType, ValidatesOnDataErrors=True}"
Validation.ErrorTemplate="{x:Null}"/>
When an item is selected in the ComboBox list, sources IDataErrorInfo data is interrogated to see if new values are
valid. This occurs because the SelectedItem property of a set of mapped is placed on ValidatesOnDataErrors true. Since the
data source is an object CustomerViewModel, mapping system, and ask for a''CustomerViewModel property of
CustomerType validation errors. In most of the time, all require validation errors CustomerViewModel delegation to a
Customer object it contains. Somehow, decand Customer has no notion of having the property of unselected state
IsCompany class CustomerViewModel must handle new items in box ComboBox control. This code can be seen in the
following listing:
if (propertyName == "CustomerType")
{
// The IsCompany property of the Customer class
// is Boolean, so it has no concept of being in
// an "unselected" state. The CustomerViewModel
// class handles this mapping and validation.
error = this.ValidateCustomerType();
}
else
{
error = (_customer as IDataErrorInfo)[propertyName];
}
return error;
}
}
The key aspect of this code is that implementation of IDataErrorInfo CustomerViewModel class can handle
specific requirements for property for ViewModel and delegating other requests by the Customer object. This allows the use
of validation logic and model classes with additional validation for the properties that make sense for ViewModel classes.
Ability to save a CustomerViewModel is available through the property of CustomerViewModel view to decide if
it can save itself and what to do when it receives the request for relief of his condition. In this application, saving a new
customer means of adding a CustomerRepository. Customer must be asked whether the object is valid or not, and must
decide if CustomerViewModel valid. This two-part decision is necessary because the specific properties of ViewModel and
examination prior validation. Logical saving for CustomerViewModel is shown in Figure 6.
if (this.IsNewCustomer)
_customerRepository.AddCustomer(_customer);
base.OnPropertyChanged("DisplayName");
}
bool IsNewCustomer
{
get { return !_customerRepository.ContainsCustomer(_customer); }
}
bool CanSave
{
get { return String.IsNullOrEmpty(this.ValidateCustomerType())
&& _customer.IsValid; }
}
ViewModel used here is much easier to create sites that can display view a Customer object and allowing for things
like status "unselected" a Boolean properties. It also provides the ability to say in an easy way to save his client state. If your
view is mapped directly to a Customer object, your view will require much more code to make the property of working in a
prosperous way. MVVM a well-defined architecture, your codebehind to view most sites should be empty or contain code to
handle checks and resources contained in that view. Sometimes you need to write code in your codbehind a view to interact
with an object ViewModel as an event or call a method that can be very difficult altcumva invoked ViewModel himself.
17
Listing 14 CollectionViewSource
<!-- In AllCustomersView.xaml -->
<CollectionViewSource
x:Key="CustomerGroups"
Source="{Binding Path=AllCustomers}"
>
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="IsCompany" />
</CollectionViewSource.GroupDescriptions>
<CollectionViewSource.SortDescriptions>
<!--
Sort descending by IsCompany so that the ' True' values appear first,
which means that companies will always be listed before people.
-->
<scm:SortDescription PropertyName="IsCompany" Direction="Descending" />
<scm:SortDescription PropertyName="DisplayName" Direction="Ascending" />
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
The user interface is the property of TotalSelectedSales maps and apply the format for the local currency value.
ViewModel subject may apply the current format, replace the view, by returning a string replace the value of property of
type Double TotalSelectedSales. ContentStringFormat properties of ContentPresenter was added in. NET Framework 3.5
SP1, so if you need to use older versions of WPF, it takes money and apply formatting to the following code:
18
Bibliography
19