/V4/Quickstarts/View-Switching Navigation/Silverlight/View-Switching Navigation/ViewSwitchingNavigation.Email/ViewModels/InboxViewModel.cs

# · C# · 163 lines · 105 code · 17 blank · 41 comment · 3 complexity · 6f5476213f4b3c115533e399e5866e8a MD5 · raw file

  1. //===================================================================================
  2. // Microsoft patterns & practices
  3. // Composite Application Guidance for Windows Presentation Foundation and Silverlight
  4. //===================================================================================
  5. // Copyright (c) Microsoft Corporation. All rights reserved.
  6. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
  7. // OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
  8. // LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  9. // FITNESS FOR A PARTICULAR PURPOSE.
  10. //===================================================================================
  11. // The example companies, organizations, products, domain names,
  12. // e-mail addresses, logos, people, places, and events depicted
  13. // herein are fictitious. No association with any real company,
  14. // organization, product, domain name, email address, logo, person,
  15. // places, or events is intended or should be inferred.
  16. //===================================================================================
  17. using System;
  18. using System.Collections.ObjectModel;
  19. using System.ComponentModel;
  20. using System.ComponentModel.Composition;
  21. using System.Text;
  22. using System.Threading;
  23. using System.Windows.Data;
  24. using System.Windows.Input;
  25. using Microsoft.Practices.Prism;
  26. using Microsoft.Practices.Prism.Commands;
  27. using Microsoft.Practices.Prism.Regions;
  28. using Microsoft.Practices.Prism.ViewModel;
  29. using ViewSwitchingNavigation.Email.Model;
  30. using ViewSwitchingNavigation.Infrastructure;
  31. namespace ViewSwitchingNavigation.Email.ViewModels
  32. {
  33. [Export]
  34. public class InboxViewModel : NotificationObject
  35. {
  36. private const string ComposeEmailViewKey = "ComposeEmailView";
  37. private const string ReplyToKey = "ReplyTo";
  38. private const string EmailViewKey = "EmailView";
  39. private const string EmailIdKey = "EmailId";
  40. private readonly SynchronizationContext synchronizationContext;
  41. private readonly IEmailService emailService;
  42. private readonly IRegionManager regionManager;
  43. private readonly DelegateCommand<object> composeMessageCommand;
  44. private readonly DelegateCommand<object> replyMessageCommand;
  45. private readonly DelegateCommand<EmailDocument> openMessageCommand;
  46. private readonly ObservableCollection<EmailDocument> messagesCollection;
  47. private static Uri ComposeEmailViewUri = new Uri(ComposeEmailViewKey, UriKind.Relative);
  48. [ImportingConstructor]
  49. public InboxViewModel(IEmailService emailService, IRegionManager regionManager)
  50. {
  51. this.synchronizationContext = SynchronizationContext.Current ?? new SynchronizationContext();
  52. this.composeMessageCommand = new DelegateCommand<object>(this.ComposeMessage);
  53. this.replyMessageCommand = new DelegateCommand<object>(this.ReplyMessage, this.CanReplyMessage);
  54. this.openMessageCommand = new DelegateCommand<EmailDocument>(this.OpenMessage);
  55. this.messagesCollection = new ObservableCollection<EmailDocument>();
  56. this.Messages = new PagedCollectionView(this.messagesCollection);
  57. this.Messages.CurrentChanged += (s, e) =>
  58. this.replyMessageCommand.RaiseCanExecuteChanged();
  59. this.emailService = emailService;
  60. this.regionManager = regionManager;
  61. this.emailService.BeginGetEmailDocuments(
  62. r =>
  63. {
  64. var messages = this.emailService.EndGetEmailDocuments(r);
  65. this.synchronizationContext.Post(
  66. s =>
  67. {
  68. foreach (var message in messages)
  69. {
  70. this.messagesCollection.Add(message);
  71. }
  72. },
  73. null);
  74. },
  75. null);
  76. }
  77. public ICollectionView Messages { get; private set; }
  78. public ICommand ComposeMessageCommand
  79. {
  80. get { return this.composeMessageCommand; }
  81. }
  82. public ICommand ReplyMessageCommand
  83. {
  84. get { return this.replyMessageCommand; }
  85. }
  86. public ICommand OpenMessageCommand
  87. {
  88. get { return this.openMessageCommand; }
  89. }
  90. private void ComposeMessage(object ignored)
  91. {
  92. // todo: 02 - New Email: Navigating to a view in a region
  93. // Any region can be navigated by passing in a relative Uri for the email view name.
  94. // By the default, the navigation service will look for an item already in the region
  95. // with a type name that matches the Uri.
  96. //
  97. // If an item is not found in the region, the navigation services uses the
  98. // ServiceLocator to find an item that matches the Uri, in the example below it would
  99. // be ComposeEmailView.
  100. this.regionManager.RequestNavigate(RegionNames.MainContentRegion, ComposeEmailViewUri);
  101. }
  102. private void ReplyMessage(object ignored)
  103. {
  104. // todo: 03 - Reply Email: Navigating to a view in a region with context
  105. // When navigating, you can also supply context so the target view or
  106. // viewmodel can orient their data to something appropriate. In this case,
  107. // we've chosen to pass the email id in a name/value pair as part of the Uri.
  108. //
  109. // The recipient of the context can get access to this information by
  110. // implementing the INavigationAware or IConfirmNavigationRequest interface, as shown by the
  111. // the ComposeEmailViewModel.
  112. //
  113. var currentEmail = this.Messages.CurrentItem as EmailDocument;
  114. var builder = new StringBuilder();
  115. builder.Append(ComposeEmailViewKey);
  116. if (currentEmail != null)
  117. {
  118. var query = new UriQuery();
  119. query.Add(ReplyToKey, currentEmail.Id.ToString("N"));
  120. builder.Append(query);
  121. }
  122. this.regionManager.RequestNavigate(RegionNames.MainContentRegion, new Uri(builder.ToString(), UriKind.Relative));
  123. }
  124. private bool CanReplyMessage(object ignored)
  125. {
  126. return this.Messages.CurrentItem != null;
  127. }
  128. private void OpenMessage(EmailDocument document)
  129. {
  130. // todo: 04 - Open Email: Navigating to a view in a region with context
  131. // When navigating, you can also supply context so the target view or
  132. // viewmodel can orient their data to something appropriate. In this case,
  133. // we've chosen to pass the email id in a name/value pair as part of the Uri.
  134. //
  135. // The EmailViewModel retrieves this context by implementing the INavigationAware
  136. // interface.
  137. //
  138. var builder = new StringBuilder();
  139. builder.Append(EmailViewKey);
  140. var query = new UriQuery();
  141. query.Add(EmailIdKey, document.Id.ToString("N"));
  142. builder.Append(query);
  143. this.regionManager.RequestNavigate(RegionNames.MainContentRegion, new Uri(builder.ToString(), UriKind.Relative));
  144. }
  145. }
  146. }