This article is in continuation of my previous article MVVM Architecture When Using Webservices For Database Interaction. Let's see how to use the events and commands described in the previous article.
- First of all, for differentiating between the Views from where the command has been received and what to send in return to that view result, we have used a GUID variable named as token.
So, let's define the Guid variable _token in CompanyDetail View and ViewModel.
Let's create a helper class to send a request and get a response for View navigation.
- Message helper or appMessage.
- Message helper: We will use it to get response from a command.
Let's start by taking an example.
We will be creating a View (Window) for company details and then, we need to match if those details occur in our database. Let's do it step by step.
Step 1
Create the architecture as discussed in previous article, MVVM Architecture When Using Webservices For Database Interaction.
Step 2
Add a window under View section in main project. I named it as CompanyDetails.
- <Window x:Class="MVVMAndWebService.Views.CompanyDetails" x:Name="This"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- Title="CompanyDetails" Height="400" Width="500" Loaded="Window_Loaded">
- <Grid >
- <Grid.RowDefinitions>
- <RowDefinition Height="63"></RowDefinition>
- <RowDefinition Height="*"></RowDefinition>
- <RowDefinition Height="10"></RowDefinition>
- </Grid.RowDefinitions>
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="10"></ColumnDefinition>
- <ColumnDefinition Width="*"></ColumnDefinition>
- <ColumnDefinition Width="10"></ColumnDefinition>
- </Grid.ColumnDefinitions>
- <Border BorderThickness="0"
- Grid.Row="0"
- Grid.ColumnSpan="3"
- BorderBrush="Transparent"
- Grid.Column="0">
- <Image x:Name="logoImage"
- Stretch="UniformToFill" Width="140" HorizontalAlignment="Left"
- Margin="0,5,20,0">
- </Image>
- </Border>
- <Grid Grid.Column="1" Margin="0,37,0,26" Grid.RowSpan="2">
- <Grid.RowDefinitions>
- <RowDefinition Height="40"></RowDefinition>
- <RowDefinition Height="40"></RowDefinition>
- <RowDefinition Height="40"></RowDefinition>
- <RowDefinition Height="70"></RowDefinition>
- </Grid.RowDefinitions>
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="171*"></ColumnDefinition>
- <ColumnDefinition Width="80*"></ColumnDefinition>
- <ColumnDefinition Width="176*"/>
- </Grid.ColumnDefinitions>
- <Label x:Name="lblCompanyName"
- Content="Name : "
- FontSize="14"
- HorizontalAlignment="Right"
- VerticalAlignment="Center"
- Grid.Row="0"
- Grid.Column="0" Margin="0,6">
- </Label>
- <TextBox x:Name="TextBoxCompanyName"
- Width="200"
- MaxLength="50"
- Grid.Column="1"
- Grid.Row="0"
- TabIndex="0"
- Text="{Binding CompanyName}" Grid.ColumnSpan="2" Margin="0,6,0,7">
- </TextBox>
- <Label x:Name="lblUserName"
- Content="User Name : "
- FontSize="14"
- HorizontalAlignment="Right"
- VerticalAlignment="Center"
- Grid.Row="1"
- Grid.Column="0" Margin="0,6"
- >
- </Label>
- <TextBox x:Name="TextBoxUserName"
- Width="200"
- MaxLength="50"
- Grid.Column="1"
- Grid.Row="1"
- TabIndex="0"
- Text="{Binding UserName}" Grid.ColumnSpan="2" Margin="0,7,0,6">
- </TextBox>
- <Label x:Name="lblPassword"
- Content="Password : "
- FontSize="14"
- HorizontalAlignment="Right"
- VerticalAlignment="Center"
- Grid.Row="2"
- Grid.Column="0" Margin="0,6">
- </Label>
- <PasswordBox x:Name="TextBoxPassword"
- Width="200"
- MaxLength="50"
- Grid.Column="1"
- Grid.Row="2"
- TabIndex="0" Grid.ColumnSpan="2" Margin="13,2,40,11"
- >
- </PasswordBox>
- <StackPanel Grid.Row="3" Orientation="Horizontal" HorizontalAlignment="Stretch"
- Grid.Column="0" Grid.ColumnSpan="3" Margin="0,76,0,-76">
- <Button x:Name="ButtonSave"
- FontSize="20"
- HorizontalAlignment="Right"
- Width="100"
- Height="50"
- Margin="50,10,0,11"
- Content="Save"
- Command="{Binding SaveCompanyCommand}"
- CommandParameter="{Binding ElementName=This}"
- TabIndex="7" IsDefault="True"/>
- <Button x:Name="ButtonCancel"
- FontSize="20"
- Margin="20,10,0,11"
- Command="{Binding CancelCompanyCommand}"
- CommandParameter="{Binding ElementName=This}"
- HorizontalAlignment="Left"
- Width="90"
- Height="50"
- Content="Cancel"
- TabIndex="8" IsCancel="True" />
- </StackPanel>
- </Grid>
- </Grid>
- </Window>
Step 3
On cs page of the above View, let's define a property GUID _token, to differentiate the requests received from Views.
Then, as we know the password will be a secured string, to get the value of the passwordBox, we cannot use the direct bindings as we have used in case of other textboxes. Please see the XAML provided above. Password is yet not bound to any property of ViewModel.
So, we need to implement an interface to the View which will be used to access the password string. So, this interface will help the View to get secure password string and that can be converted back to insecure string in View Model.
Binding for commands is done on Buttons.
Let's create an interface to the CommonClasses for above purpose, which will contain the below code.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace CommonClasses
- {
- public interface IHavePassword
- {
- System.Security.SecureString Password { get; }
- }
- }
Now, for getting the response as we have discussed earlier, we will be receiving the message at the end of each command. So, let's create a Message class as a helper. Keep it separate from the above architecture and add Helper project to the existing solution.

As you can see from the above screenshot, we need to create a class ‘Message’ containing the message properties.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace Helper
- {
- public class Message
- {
- public string Type;
- public object Data;
- }
- }
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace Helper
- {
- public interface IMessageTarget
- {
- Guid Token { get; }
- void ReceiveMessage(Message msg);
- }
- }
Token will differentiate between the requests from different Views. Let's create static class to send response to the Views.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace Helper
- {
- public static class AppMessage
- {
- static Dictionary<Guid, IMessageTarget> _registerWindow = new Dictionary<Guid, IMessageTarget>();
- //Register a view.
- public static void Register(IMessageTarget View, Guid token)
- {
- if (_registerWindow.ContainsKey(token))
- {
- _registerWindow.Remove(token);
- }
- _registerWindow.Add(token, View);
- }
- //Send response
- public static void Send(Guid token, Message notification)
- {
- if (_registerWindow.ContainsKey(token))
- {
- _registerWindow[token].ReceiveMessage(notification);
- }
- }
- //unregister that view.
- public static void UnRegister(Guid token)
- {
- if (_registerWindow.ContainsKey(token))
- {
- _registerWindow.Remove(token);
- }
- }
- }
- }
- Register a View by token.
- Send response.
- Unregister that View.
OK. As per the above understanding, our View should contain GUID property token, Message response Method from IMessage, Password string property from IhavePassword.

Akshay PhadkePosted Jan 18, 2017, 12:05 AM
Very well written Neha............
RakeshPosted Jan 17, 2017, 1:27 PM
Good share.....................