How to Send an Email Using the Cimbalino Windows Phone Toolkit (Using MVVM)

Introduction

The Cimbalino Windows Phone Toolkit delivers a set of useful and powerful MVVM-compatible tools and services to help developers build Silverlight applications for Windows Phone.

The toolkit is divided into projects that deliver different features, ranging from base MVVM services and helpers, through to code for background agents and for accessing media library, location services and so on.

The Cimbalino Toolkit's "Email Compose" service is an MVVM compatible wrapper around the system EmailComposeTask that can be used to launch a dialog to email users. The kit provides both the IEmailComposeService interface and its implementation EmailComposeService required to register the service in MVVM Light (note that MVVM and the MVVM Light Toolkit are not "preconditions" to use this service).

Screenshot of the example app:



Building the Example Code

The source code for the code example is available here: EmailComposeService (Github).

To build the source code you will also need the MVVM Light Toolkit and the Cimbalino Windows Phone Toolkit. Their packages are available in the Nuget Package Manager .

The Sample

Registering the Service

Register the service in the ViewModelLocator constructor as shown below:

  1. /// This class contains static references to all the view models in the  
  2. /// application and provides an entry point for the bindings.  
  3. public class ViewModelLocator  
  4. {  
  5.     /// Initializes a new instance of the ViewModelLocator class.  
  6.     public ViewModelLocator()  
  7.     {  
  8.         ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);  
  9.         if (!SimpleIoc.Default.IsRegistered<IEmailComposeService>())  
  10.         {  
  11.             SimpleIoc.Default.Register<IEmailComposeService, EmailComposeService>();  
  12.         }  
  13.         SimpleIoc.Default.Register<MainViewModel>();  
  14.     }  
  15.   
  16.     public MainViewModel MainViewModel  
  17.     {  
  18.         get  
  19.         {  
  20.             return ServiceLocator.Current.GetInstance<MainViewModel>();  
  21.         }  
  22.     }  
  23.   
  24.     public static void Cleanup()  
  25.     {  
  26.         // TODO Clear the ViewModels  
  27.     }  

Implementing the ViewModel

Implement the MainViewModel as shown below. The highlighted sections show the MainViewModel constructor taking the IEmailComposeService parameter and assigning it to the private variable. Later on the private member is used to show the link service.

  1. /// This class contains properties that the main View can data bind to.  
  2. public class MainViewModel : ViewModelBase  
  3. {  
  4.     /// The public application url.  
  5.     private readonly string _appUrl;  
  6.     /// The email compose service.  
  7.     private readonly IEmailComposeService _emailComposeService;  
  8.     /// The message  
  9.     private string _message;  
  10.     /// The subject  
  11.     private string _subject;  
  12.     /// The to  
  13.     private string _to;  
  14.   
  15.     /// Initializes a new instance of the email Compose Service.  
  16.     public MainViewModel(IEmailComposeService emailComposeService)  
  17.     {  
  18.         _emailComposeService = emailComposeService;  
  19.         SendFeedbackCommand = new RelayCommand(SendFeedback);  
  20.         ShareToMailCommand = new RelayCommand(ShareToMail);  
  21.         SendCommand =new RelayCommand(Send);  
  22.         _appUrl = string.Concat("http://windowsphone.com/s?appid=8df00038-1b7a-406b-b33f-37a78b17348c ");  
  23.     }  
  24.   
  25.     /// Gets or sets the message.  
  26.     public string Message  
  27.     {  
  28.         get { return _message; }  
  29.         set { Set("Message"ref _message, value); }  
  30.     }  
  31.     /// Gets the send command.  
  32.     public ICommand SendCommand { getprivate set; }  
  33.     /// Gets the send feedback command.  
  34.     public ICommand SendFeedbackCommand { getprivate set; }  
  35.     /// Gets the share to e-mail command.  
  36.     public ICommand ShareToMailCommand { getprivate set; }  
  37.     /// Gets or sets the subject.  
  38.     public string Subject  
  39.     {  
  40.         get { return _subject; }  
  41.         set { Set("Subject"ref _subject, value); }  
  42.     }  
  43.     /// Gets or sets to.  
  44.     public string To  
  45.     {  
  46.         get { return _to; }  
  47.         set { Set("To"ref _to, value); }  
  48.     }  
  49.     /// Sends mails.  
  50.     private void Send()  
  51.     {  
  52.         if (!string.IsNullOrEmpty(To) && !string.IsNullOrEmpty(Subject) && !string.IsNullOrEmpty(Message))  
  53.         {  
  54.             _emailComposeService.Show(To, Subject, Message);  
  55.         }  
  56.     }  
  57.     /// The send feedback.  
  58.     private void SendFeedback()  
  59.     {  
  60.         const string to = "saramgsilva@gmail.com";  
  61.         const string subject = "My Feedback";  
  62.         var body = "This the body";  
  63.         _emailComposeService.Show(to, subject, body);  
  64.     }  
  65.     /// The share to mail.  
  66.     private void ShareToMail()  
  67.     {  
  68.         const string Subject = "Cimbalino Toolkit Sample";  
  69.         var body = string.Concat("This application is amazing, you should try it! See in", _appUrl);  
  70.         _emailComposeService.Show(Subject, body);  
  71.     }  

Implementing the View

The rest of the app is "plumbing" to hook up the MainViewModel to the View and send commands back to the invoke the service.

Add the binding to the main page as shown:

  1. DataContext="{Binding MainViewModel, Source={StaticResource Locator}}" 

The MainPage.xaml can be the following:

  1. <phone:PhoneApplicationPage x:Class="CimbalinoSample.MainPage"  
  2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation "  
  3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml "  
  4. xmlns:cimbalino="clr-namespace:Cimbalino.Phone.Toolkit.Behaviors;assembly=Cimbalino.Phone.Toolkit"  
  5. xmlns:d="http://schemas.microsoft.com/expression/blend/2008 "  
  6. xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"  
  7. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006 "  
  8. xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"  
  9. xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"  
  10. DataContext="{Binding MainViewModel,  
  11. Source={StaticResource Locator}}"  
  12. FontFamily="{StaticResource PhoneFontFamilyNormal}"  
  13. FontSize="{StaticResource PhoneFontSizeNormal}"  
  14. Foreground="{StaticResource PhoneForegroundBrush}"  
  15. Orientation="Portrait"  
  16. SupportedOrientations="Portrait"  
  17. shell:SystemTray.IsVisible="True"  
  18. mc:Ignorable="d">  
  19.   
  20.     <!-- LayoutRoot is the root grid where all page content is placed -->  
  21.         <Grid x:Name="LayoutRoot" Background="Transparent">  
  22.             <Grid.RowDefinitions>  
  23.                 <RowDefinition Height="Auto" />  
  24.                 <RowDefinition Height="*" />  
  25.             </Grid.RowDefinitions>  
  26.   
  27.         <!-- TitlePanel contains the name of the application and page title -->  
  28.             <StackPanel x:Name="TitlePanel" Grid.Row="1" Margin="0,5,12,396">  
  29.                 <TextBlock Margin="12,0" Style="{StaticResource PhoneTextTitle2Style}" Text="Cimbalino Toolkit Sample" />  
  30.             </StackPanel>  
  31.             <TextBlock Grid.RowSpan="2" Margin="12,50,-3,639" Style="{StaticResource PhoneTextTitle3Style}" TextWrapping="Wrap">  
  32.                 This samples has the goal to show how to use Cimbalino Toolkit - EmailComposeService.  
  33.             </TextBlock>  
  34.         <!-- ContentPanel - place additional content here -->  
  35.         <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,150,12,0">  
  36.             <Grid.RowDefinitions>  
  37.                 <RowDefinition Height="Auto" />  
  38.                 <RowDefinition Height="Auto" />  
  39.                 <RowDefinition Height="Auto" />  
  40.                 <RowDefinition Height="Auto" />  
  41.                 <RowDefinition Height="Auto" />  
  42.                 <RowDefinition Height="Auto" />  
  43.                 <RowDefinition Height="Auto" />  
  44.                 <RowDefinition Height="Auto" />  
  45.             </Grid.RowDefinitions>  
  46.             <TextBlock Grid.Row="0" Text="To:" />  
  47.             <TextBox Grid.Row="1" Text="{Binding To, Mode=TwoWay}" />   
  48.             <TextBlock Grid.Row="2" Text="Subject:" />  
  49.             <TextBox Grid.Row="3" Text="{Binding Subject, Mode=TwoWay}" />  
  50.             <TextBlock Grid.Row="4" Text="Message:" />  
  51.             <TextBox Grid.Row="5" Height="200" Text="{Binding Message, Mode=TwoWay}" />  
  52.             <Button Grid.Row="6" Command="{Binding SendCommand}" Content="Send" />  
  53.         </Grid>  
  54.     <i:Interaction.Behaviors>  
  55.         <cimbalino:ApplicationBarBehavior>  
  56.             <cimbalino:ApplicationBarIconButton Command="{Binding SendFeedbackCommand, Mode=OneTime}" IconUri="/Images/appbar.reply.email.png" Text="Feedback" />  
  57.                 <cimbalino:ApplicationBarIconButton Command="{Binding ShareToMailCommand, Mode=OneTime}" IconUri="/Images/appbar.email.png" Text="Email" />  
  58.                 </cimbalino:ApplicationBarBehavior>  
  59.         </i:Interaction.Behaviors>  
  60.     </Grid>  
  61. </phone:PhoneApplicationPage> 

Source Code Files

  • ViewModelLocator.cs has the ViewModelLocator class that helps to bind the view model with the view.
  • MainViewModel.cs has the MainViewModel class that represents the view model for the main page.
  • MainPage.xaml and MainPage.xaml.cs represent the main page.

See Also