Loosely Coupled Silverlight 4 applications using Prism 4 and Commanding

Posted by: Mahesh Sabnis , on 1/20/2011, in Category Silverlight 2, 3, 4 and 5
Views: 35324
Abstract: In this article, we will how to use DelegateCommand for implementing loosely coupled applications in Silverlight 4 using Prism 4.

For developing loosely coupled applications using Silverlight 4 or WPF, it is suggested that Prism 4 libraries be used in most scenarios. These libraries provide various features like Modularity, UI Composition, EventAggregator, MVVM using DelegateCommand and CompositeCommand etc. All these features are important for building Composite applications. In this article, we will how to use DelegateCommand for implementing loosely  coupled Silverlight 4 applications using Prism 4.

If you are new to Prism 4, I would strongly suggest you first read my previous article Using Prism with Silverlight 4, where I have introduced Prism and explained some important concepts in Prism that we will using in this article.

The DelegateCommand class is inherited from DelegateCommandBase class which implements the ICommand interface. The DelegateCommand constructor accepts two parameters of the type Action<T>. This first parameter represents the actual method (the Execute) to be executed which further can make a call to a Service method. The second parameter defines the Conditional method which returns a Boolean value. If this value is true, then the Execute method will be executed, else will be ignored because the UI element (e.g. Button) is disabled. Read the article to understand this better.

For this article I have used following table:

patient table

Creating WCF Service

This service defines methods for performing Insert and Read operations.

The WCF Service contains the following interface and DataContracts (Note: You can use ADO.NET EF, however to keep things simple, I will go ahead with the approach shown below)

ipatient service

The above interface is implemented in the service as shown below:

patient service

The WCF Service is hosted in IIS.

Creating Silverlight 4.0 Client Application

In this section, I have used a Silverlight application and class libraries targeting Silverlight 4.0.

Step 1: Open VS2010 and create a blank solution, name it as ‘SL4_MVVM_Using_Prism’. In this solution, add a new Silverlight application andname it as ‘SL_MVVM_Prism_Client’. In this project, add the following Prism 4 library references:

  • Microsoft.Practices.Prism.
  • Microsoft.Practices.Prism.UnityExtensions.
  • Microsoft.Practices.ServiceLocation.
  • Microsoft.Practices.Unity.Silverlight

Step 2: Rename MainPage.xaml to ‘Shell.xaml’, also replace MainPage class name from the code behind and from the .xaml file. In the .xaml file, refer to the CodePlex namespace for Prism and add the Regions using ItemsControls. The XAML code will be as below:

Shell XAML 

Step 3: This application displays two separate user interfaces for displaying all patients and registration patients. In the same solution, add the following Silverlight class libraries:

  • PatientInfoModule - Used for displaying all Patients.
  • RegisterPatientModule - Used to register patients.
  • SL4_ServiceAgent - Used to act as a Service Agent between the Silverlight Application and the WCF service.

Add the following references in ‘PatientInfoModule’ and ‘RegisterPatientModule’ projects:

  • Microsoft.Practices.Prism.
  • Microsoft.Practices.Prism.UnityExtensions.
  • Microsoft.Practices.ServiceLocation.
  • Microsoft.Practices.Unity.Silverlight

Step 4: In the ‘SL4_ServiceAgent’, add the WCF Service reference. In this library rename ‘Class1.cs’ to ‘ServiceAdapter.cs’ and write the following code in it:

silverlightserviceagent

In the above code, define the Service Adapter interface and the Service adapter class. This class makes a call to the WCF service asynchronously.

Build the project and add its reference in ‘PatientInfoModule’ and ‘RegisterPatientModule’.

Step 5: In the ‘PatientInfoModule’ project, add ‘ViewModel’ or ‘Model’ (whatever name you prefer) and ‘Views’ folder. In the Model folder, add a new class file and name it as ‘PatientsModel.cs’. This class defines ‘DelegateCommand’ which will decide whether to read all patients information by executing ‘PatientRead’ method. This class also makes a call to the ServiceAgent for further making calls to the WCF service. The code of the class is as below:

Patients Model 

Step 6: In the View folder, add a new Silverlight user control. Name it as ‘PatientsView.xaml’. Write the following XAML in it. This binds the view with the class created in the step above:

Patients View 

Step 7: In the ‘PatientInfoModule’ project add a new class file and name it as ‘PatientsModule.cs’. This class will define module and write the mechanism for registering the View in the module to the region define in Shell.Xaml. The code is as below :

Patients Module 

Step 8: Build the project and add its reference in ‘SL_MVVM_Prism_Client’ project.

Step 9: In the ‘RegisterPatientModule’ project, add ‘ViewModel or Model’ folder and View Folder.

Step 10: In the Model folder add a new class file, name it as ‘RegistrationPatientModel.cs’. Write the following code in it. This will also define proxy for the Service Adapter and DelegateCommand whioch use Execute method for performing PatientRegistration operation. The code is as below:

Register Patient Model

Step 11: In the View folder, add a new Silverlight UserControl and name it as ‘RegisterPatientView.xaml’. This will bind with the class created above. The XAML code is as shown below:

Register Patient View xaml

The DelegateCommand is bind with the button of name ‘btnRegisterPatient’.

Step 12: In the project, add a new class file and name it as ‘RegistrationPatientModule.cs’. This will define the module class as below:

registratio patient module

Build the project and add its reference in ‘SL_MVVM_Prism_Client’ project.

Step 13: In the ‘SL_MVVM_Prism_Client’ project, add the ‘ServiceReferences.ClientConfig’ which is generated when you add the WCF service reference in ‘SL4_ServiceAgent’. This is required to locate the service because the ‘SL_MVVM_Prism_Client’ is the startup project which has capability to parse the .config file.

Step 14: Add the new class file of name ‘BootStrapper.cs’ in the client project. This will be inherited from UnityBootstrapper class and define mechanism for loading module and initializing the shell. The code is as shown below:

Boot Strapper

The ConfigureCatalog() method adds the module created in above steps in the ModuleCatalog.

Step 15: Modify the Application_StartUp method of the App.Xaml.cs file as below:

App Startup

This will create an instance of the BootStrapper class and run it.

Step 16: Run the application and the following result will be displayed:

Silverlight Prism App

After clicking on ‘Load Patients’ button, the patient result is displayed in the DataGrid. Similarly you can click on the ‘Register Patient’ button to register the patient.

Conclusion: DelegateCommand class provides an out-of-Box mechanism to implement MVVM in Prism 4. We have also been provided by ‘CompositeComponent’ which collects all DelegateCommand from the child Views and if the Execute of the individual child View is successful, only then the CompositeCommand can be executed. Further you can make use of IEventAggregator mechanism to establish communication between Views.

The entire source code of this article can be downloaded over here

Was this article worth reading? Share it with fellow developers too. Thanks!
Share on LinkedIn
Share on Google+
Further Reading - Articles You May Like!
Author
Mahesh Sabnis is a DotNetCurry author and Microsoft MVP having over 17 years of experience in IT education and development. He is a Microsoft Certified Trainer (MCT) since 2005 and has conducted various Corporate Training programs for .NET Technologies (all versions). Follow him on twitter @maheshdotnet


Page copy protected against web site content infringement 	by Copyscape




Feedback - Leave us some adulation, criticism and everything in between!
Comment posted by Mike Long on Friday, January 21, 2011 3:16 AM
Thank you for both the prism articles. Thoroughly enjoyed reading them
Comment posted by Mahesh Sabnis on Friday, January 21, 2011 4:47 AM
Hi Mike,
  Thanks a lot, there is more yet to come.
Mahesh Sabnis
Comment posted by Javin@Tibco RV Tutorial on Friday, January 21, 2011 9:16 AM
Thanks for presenting this nice article buddy, enjoyed reading.

Javin
<a href="http://javarevisited.blogspot.com/2010/10/how-to-check-if-thread-has-lock-on.html" title="How to check if a thread holds a lock">
How to check if a thread holds a lock </a>
<a href="http://javarevisited.blogspot.com/search/label/FIX%20protocol%20tutorial" title="Fix Protocol tutorial">FIX Protocol tutorial</a>
Comment posted by Neeraj Singh on Monday, January 31, 2011 2:57 AM
Dear Sir,
I have downloaded the source code and also created as suggested table in my database.
Once I tried to run the application, UI will displayed without data in "Patient in Hospital" grid. Even I have seen WCF Service response with the data at debug time.
Can you please suggest me the missing steps.

Regards,
Neeraj Singh
Comment posted by Mahesh Sabnis on Monday, January 31, 2011 4:18 AM
Hi Neeraj,
Can you please check the DataBinding Expression of DataGrid with 'Patients' collection. If it is not loaded then the DataGrid Will not show any records.
Thanks
Mahesh Sabnis
Comment posted by Marc Blasi on Sunday, February 13, 2011 5:41 PM
Very nice.  Well documented and easy to apply to future projects. Thanks for demystifying Prism and applying it to silverlight in a straight forward method. Wonder if you have used ninject? I just began using it for MVC 3 apps in a similar manner. Keep up the good work.
Comment posted by MAhesh Sabnis on Saturday, April 30, 2011 1:56 AM
Hi Marc,
   Thanks a lot.
Regards
Mahesh Sabnis
Comment posted by Maria Castiglione on Thursday, June 16, 2011 4:09 PM
Just what I have been looking for! Can you help me convert this to use MEF?
Comment posted by MarkusR on Thursday, August 11, 2011 4:51 PM
I am a little lost on how to handle events...

I am trying to maintain the MVVM pattern and have no code behind. How would I handle this with a delegatecommand?

private void scheduler_AppointmentCreating(objectsender, AppointmentCreatingEventArgs e)  
{  
    e.Cancel = true;  
    ....
}

In particular, how do I handle the e.Cancel???

XAML:

        <telerik:RadScheduler x:Name="schTasks"
                              telerik:StyleManager.Theme="Vista" AppointmentsSource="{Binding Visits}" AvailableViewModes="All"
                              MonthViewScrollBarVisibility="Collapsed" CalendarVisibility="Visible" IsReadOnly="False"
                              IsInlineEditingEnabled="False" OpenModalDialogs="True" Margin="0,34,0,0" AllowDrop="False"
                              >
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="AppointmentEditing">
                    <i:InvokeCommandAction Command="{Binding GetCurrentAppointmentCommand}"
                                           CommandParameter="{Binding ElementName=schTasks,Mode=OneWay}"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>

        </telerik:RadScheduler>

ViewModel:

        private readonly DelegateCommand<object> _getCurrentAppointmentCommand;
        public ICommand GetCurrentAppointmentCommand
        {
            get { return _getCurrentAppointmentCommand; }
        }

        [ImportingConstructor]
        public VisitsViewModel(IVisitsService VisitsService, IRegionManager regionManager)
        {            
          ...

            _getCurrentAppointmentCommand =
                new DelegateCommand<object>(GetCurrentAppointment);

        }

        public void GetCurrentAppointment(object param)
        {
            if (param != null)
            {
                var appt = ((RadScheduler)param).SelectedAppointment;
            }
        }

-Markus
Comment posted by MarkusR on Thursday, August 11, 2011 5:53 PM
I am a little lost on how to handle events...

I am trying to maintain the MVVM pattern and have no code behind. How would I handle this with a delegatecommand?

private void scheduler_AppointmentCreating(objectsender, AppointmentCreatingEventArgs e)  
{  
    e.Cancel = true;  
    ....
}

In particular, how do I handle the e.Cancel???

XAML:

        <telerik:RadScheduler x:Name="schTasks"
                              telerik:StyleManager.Theme="Vista" AppointmentsSource="{Binding Visits}" AvailableViewModes="All"
                              MonthViewScrollBarVisibility="Collapsed" CalendarVisibility="Visible" IsReadOnly="False"
                              IsInlineEditingEnabled="False" OpenModalDialogs="True" Margin="0,34,0,0" AllowDrop="False"
                              >
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="AppointmentEditing">
                    <i:InvokeCommandAction Command="{Binding GetCurrentAppointmentCommand}"
                                           CommandParameter="{Binding ElementName=schTasks,Mode=OneWay}"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>

        </telerik:RadScheduler>

ViewModel:

        private readonly DelegateCommand<object> _getCurrentAppointmentCommand;
        public ICommand GetCurrentAppointmentCommand
        {
            get { return _getCurrentAppointmentCommand; }
        }

        [ImportingConstructor]
        public VisitsViewModel(IVisitsService VisitsService, IRegionManager regionManager)
        {            
          ...

            _getCurrentAppointmentCommand =
                new DelegateCommand<object>(GetCurrentAppointment);

        }

        public void GetCurrentAppointment(object param)
        {
            if (param != null)
            {
                var appt = ((RadScheduler)param).SelectedAppointment;
            }
        }

-Markus
Comment posted by Irshad Ali on Friday, January 13, 2012 1:27 AM
HI!

  Nice article , I have read and try to run your application.
  I found some following problems please can you resolve this issue
  
1)-  It is not loading the grid

2)- It is not setting the variable like  PatientsReadCompleted which is a variable of event EventHandler<DataEventArgs<PatientsModel>>

Please resolve this issue.

Thanks


Comment posted by Sandeep Mishra on Friday, February 24, 2012 1:00 AM
Good Article on Prism
Really Helpful.
Comment posted by chandra on Monday, July 30, 2012 5:46 AM
nice artical for begineers

Categories

JOIN OUR COMMUNITY

POPULAR ARTICLES

FREE .NET MAGAZINES

Free DNC .NET Magazine

Tags

JQUERY COOKBOOK

jQuery CookBook