PageRenderTime 37ms CodeModel.GetById 16ms app.highlight 15ms RepoModel.GetById 1ms app.codeStats 0ms

/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//===================================================================================
 17using System;
 18using System.Collections.ObjectModel;
 19using System.ComponentModel;
 20using System.ComponentModel.Composition;
 21using System.Text;
 22using System.Threading;
 23using System.Windows.Data;
 24using System.Windows.Input;
 25using Microsoft.Practices.Prism;
 26using Microsoft.Practices.Prism.Commands;
 27using Microsoft.Practices.Prism.Regions;
 28using Microsoft.Practices.Prism.ViewModel;
 29using ViewSwitchingNavigation.Email.Model;
 30using ViewSwitchingNavigation.Infrastructure;
 31
 32namespace ViewSwitchingNavigation.Email.ViewModels
 33{
 34    [Export]
 35    public class InboxViewModel : NotificationObject
 36    {
 37        private const string ComposeEmailViewKey = "ComposeEmailView";
 38        private const string ReplyToKey = "ReplyTo";
 39        private const string EmailViewKey = "EmailView";
 40        private const string EmailIdKey = "EmailId";
 41
 42        private readonly SynchronizationContext synchronizationContext;
 43        private readonly IEmailService emailService;
 44        private readonly IRegionManager regionManager;
 45        private readonly DelegateCommand<object> composeMessageCommand;
 46        private readonly DelegateCommand<object> replyMessageCommand;
 47        private readonly DelegateCommand<EmailDocument> openMessageCommand;
 48        private readonly ObservableCollection<EmailDocument> messagesCollection;
 49
 50        private static Uri ComposeEmailViewUri = new Uri(ComposeEmailViewKey, UriKind.Relative);
 51
 52        [ImportingConstructor]
 53        public InboxViewModel(IEmailService emailService, IRegionManager regionManager)
 54        {
 55            this.synchronizationContext = SynchronizationContext.Current ?? new SynchronizationContext();
 56
 57            this.composeMessageCommand = new DelegateCommand<object>(this.ComposeMessage);
 58            this.replyMessageCommand = new DelegateCommand<object>(this.ReplyMessage, this.CanReplyMessage);
 59            this.openMessageCommand = new DelegateCommand<EmailDocument>(this.OpenMessage);
 60
 61            this.messagesCollection = new ObservableCollection<EmailDocument>();
 62            this.Messages = new PagedCollectionView(this.messagesCollection);
 63            this.Messages.CurrentChanged += (s, e) =>
 64                this.replyMessageCommand.RaiseCanExecuteChanged();
 65
 66            this.emailService = emailService;
 67            this.regionManager = regionManager;
 68
 69            this.emailService.BeginGetEmailDocuments(
 70                r =>
 71                {
 72                    var messages = this.emailService.EndGetEmailDocuments(r);
 73
 74                    this.synchronizationContext.Post(
 75                        s =>
 76                        {
 77                            foreach (var message in messages)
 78                            {
 79                                this.messagesCollection.Add(message);
 80                            }
 81                        },
 82                        null);
 83                },
 84                null);
 85        }
 86
 87        public ICollectionView Messages { get; private set; }
 88
 89        public ICommand ComposeMessageCommand
 90        {
 91            get { return this.composeMessageCommand; }
 92        }
 93
 94        public ICommand ReplyMessageCommand
 95        {
 96            get { return this.replyMessageCommand; }
 97        }
 98
 99        public ICommand OpenMessageCommand
100        {
101            get { return this.openMessageCommand; }
102        }
103
104        private void ComposeMessage(object ignored)
105        {
106            // todo: 02 - New Email: Navigating to a view in a region
107            // Any region can be navigated by passing in a relative Uri for the email view name.
108            // By the default, the navigation service will look for an item already in the region
109            // with a type name that matches the Uri.
110            //
111            // If an item is not found in the region, the navigation services uses the 
112            // ServiceLocator to find an item that matches the Uri, in the example below it would
113            // be ComposeEmailView.
114            this.regionManager.RequestNavigate(RegionNames.MainContentRegion, ComposeEmailViewUri);
115        }
116
117        private void ReplyMessage(object ignored)
118        {
119            // todo: 03 - Reply Email: Navigating to a view in a region with context
120            // When navigating, you can also supply context so the target view or
121            // viewmodel can orient their data to something appropriate.  In this case,
122            // we've chosen to pass the email id in a name/value pair as part of the Uri.
123            //
124            // The recipient of the context can get access to this information by
125            // implementing the INavigationAware or IConfirmNavigationRequest interface, as shown by the 
126            // the ComposeEmailViewModel.
127            //
128            var currentEmail = this.Messages.CurrentItem as EmailDocument;
129            var builder = new StringBuilder();
130            builder.Append(ComposeEmailViewKey);
131            if (currentEmail != null)
132            {
133                var query = new UriQuery();
134                query.Add(ReplyToKey, currentEmail.Id.ToString("N"));
135                builder.Append(query);
136            }
137            this.regionManager.RequestNavigate(RegionNames.MainContentRegion, new Uri(builder.ToString(), UriKind.Relative));
138        }
139
140        private bool CanReplyMessage(object ignored)
141        {
142            return this.Messages.CurrentItem != null;
143        }
144
145        private void OpenMessage(EmailDocument document)
146        {
147            // todo: 04 - Open Email: Navigating to a view in a region with context
148            // When navigating, you can also supply context so the target view or
149            // viewmodel can orient their data to something appropriate.  In this case,
150            // we've chosen to pass the email id in a name/value pair as part of the Uri.
151            //
152            // The EmailViewModel retrieves this context by implementing the INavigationAware
153            // interface.
154            //
155            var builder = new StringBuilder();
156            builder.Append(EmailViewKey);
157            var query = new UriQuery();
158            query.Add(EmailIdKey, document.Id.ToString("N"));
159            builder.Append(query);
160            this.regionManager.RequestNavigate(RegionNames.MainContentRegion, new Uri(builder.ToString(), UriKind.Relative));
161        }
162    }
163}