亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

Prism4學習筆記(七):State-Based Navigation QuickStart

2019-11-11 05:01:05
字體:
來源:轉載
供稿:網友

 本節學習了Navigation的一些基本知識,覺得這節比較難。這里講學習和理解點的東西記錄下來。覺得本節應該弄清楚的問題的關鍵詞

  (1)CallMethodAction用于事件和行為的綁定。

(2)InteractionRequest<T> 在交互請求時協調ViewModel和View

(3)Notification用于交互式單向通知用戶,所以ViewModel不能預測用戶對Notification中Title和Content的更改

(4)學會自定義行為和操作

(一)在ChatView.xaml,代碼如下

View Code復制代碼<Grid Grid.Row="0" Grid.Column="1" Grid.RowSpan="2"><Grid.RowDefinitions><RowDefinition Height="Auto"/><RowDefinition Height="Auto"/></Grid.RowDefinitions><Grid.ColumnDefinitions><ColumnDefinition Width="*"/><ColumnDefinition Width="Auto"/></Grid.ColumnDefinitions><!--Send Message按鈕行為 在View中直接調用方法(InvokeCommandAction)使用CallMethodAction實現動作響應事件或者觸發器,有兩種方式獲取ViewModel的響應在松散耦合的風格中。(1)你可以用Command來時實現操作(2)你可用行為附加到元素上(附加屬性機制或使用Blend SDK中behavior基本類)Interaction.Triggers和Interaction.Behaviors.行為能與事件掛鉤CallMethodAction一般用到下面的3個屬性(1)TargetObject(2)MethodName(3)IsEnabled PRism中 DelegateCommandBlend SDK中ActonCommand --><Button x:Name="SendMessageButton" Grid.Column="0" Grid.Row="0" Margin="4" VerticalAlignment="Center"AutomationProperties.AutomationId="SendMessageButton"><i:Interaction.Triggers><i:EventTrigger EventName="Click" ><ei:CallMethodAction TargetObject="{Binding DataContext, ElementName=userControl}"MethodName="SendMessage"/></i:EventTrigger></i:Interaction.Triggers>Send Message</Button><GuidanceTools:InfoTipToggleButton VerticalAlignment="Center"Grid.Column="1" Grid.Row="0" Margin="4"><StackPanel MaxWidth="400"><TextBlock TextWrapping="Wrap">This button executes the SendMessage method on the view model,and is only enabled when no other message is being sent. Executing the method causes a child window to be opened to capture the message to send. Accepting the message causes the view modelto send the message to the chat service, which in turnscauses an update on the view model that is represented by showinga progress bar until a confirmation that the message has been sentis issued by the chat service.</TextBlock></StackPanel></GuidanceTools:InfoTipToggleButton><Button Grid.Column="0" Grid.Row="1" Margin="4" Command="{Binding ShowDetailsCommand}" VerticalAlignment="Center"><Button.CommandParameter><sys:Boolean>False</sys:Boolean></Button.CommandParameter>Go Back</Button><GuidanceTools:InfoTipToggleButton VerticalAlignment="Center"Grid.Column="1" Grid.Row="1" Margin="4"><StackPanel MaxWidth="400"><TextBlock TextWrapping="Wrap">This button uses the ShowDetailsCommand, which is only availablewhen a contact has been selected. Executing the command setsone of the 'ShowDetails' and 'ShowContacts' visual states.Transitions to this state are implemented with a flip visual effect.</TextBlock><TextBlock TextWrapping="Wrap">Visual state transitions for the detail visualization mode are triggered by changes in the view model.</TextBlock></StackPanel></GuidanceTools:InfoTipToggleButton ></Grid>復制代碼

(二)在ChatViewModel.cs

復制代碼ublic class ChatViewModel : ViewModel{private readonly IChatService chatService;//InteractionRequest<T> 在交互請求時協調ViewModel和View//(1)Raise方法允許ViewModel初始化交互和指定一個對象上下文(類型為T),并且回調方法在交互完成后被調用// 上下文對象允許ViewModel傳遞數據和狀態到View上在用交互期間//(2)如果回調方法被指定,上下文對象將被傳遞回ViewModel,this允許交互期間用戶的任何改變都可以回傳到ViewModelprivate readonly InteractionRequest<SendMessageViewModel> sendMessageRequest;private readonly InteractionRequest<ReceivedMessage> showReceivedMessageRequest;private readonly ObservableCollection<Contact> contacts;private readonly PagedCollectionView contactsView;private readonly ShowDetailsCommandImplementation showDetailsCommand;private bool showDetails;private bool sendingMessage;public ChatViewModel(IChatService chatService){this.contacts = new ObservableCollection<Contact>();this.contactsView = new PagedCollectionView(this.contacts);this.sendMessageRequest = new InteractionRequest<SendMessageViewModel>();this.showReceivedMessageRequest = new InteractionRequest<ReceivedMessage>();this.showDetailsCommand = new ShowDetailsCommandImplementation(this);this.contactsView.CurrentChanged += this.OnCurrentContactChanged;this.chatService = chatService;this.chatService.Connected = true;this.chatService.ConnectionStatusChanged += (s, e) => this.RaisePropertyChanged(() => this.ConnectionStatus);this.chatService.MessageReceived += this.OnMessageReceived;this.chatService.GetContacts(result =>{if (result.Error == null){foreach (var item in result.Result){this.contacts.Add(item);}}});}public ObservableCollection<Contact> Contacts{get { return this.contacts; }}public ICollectionView ContactsView{get { return this.contactsView; }}public IInteractionRequest SendMessageRequest{get { return this.sendMessageRequest; }}public IInteractionRequest ShowReceivedMessageRequest{get { return this.showReceivedMessageRequest; }}public string ConnectionStatus{get{return this.chatService.Connected ? "Available" : "Unavailable";}set{this.chatService.Connected = value == "Available";}}public Contact CurrentContact{get{return this.contactsView.CurrentItem as Contact;}}public bool ShowDetails{get{return this.showDetails;}set{if (this.showDetails != value){this.showDetails = value;this.RaisePropertyChanged(() => this.ShowDetails);}}}public bool SendingMessage{get{return this.sendingMessage;}private set{if (this.sendingMessage != value){this.sendingMessage = value;this.RaisePropertyChanged(() => this.SendingMessage);}}}public ICommand ShowDetailsCommand{get { return this.showDetailsCommand; }}//SendMessage綁定到Send Message按鈕public void SendMessage(){var contact = this.CurrentContact;this.sendMessageRequest.Raise(new SendMessageViewModel(contact, this),sendMessage =>{if (sendMessage.Result.HasValue && sendMessage.Result.Value){this.SendingMessage = true;this.chatService.SendMessage(contact,sendMessage.Message,result =>{this.SendingMessage = false;});}});}private void OnCurrentContactChanged(object sender, EventArgs a){this.RaisePropertyChanged(() => this.CurrentContact);this.showDetailsCommand.RaiseCanExecuteChanged();}private void OnMessageReceived(object sender, MessageReceivedEventArgs a){this.showReceivedMessageRequest.Raise(a.Message);}#region 類ShowDetailsCommandImplementationprivate class ShowDetailsCommandImplementation : ICommand{private readonly ChatViewModel owner;public ShowDetailsCommandImplementation(ChatViewModel owner){this.owner = owner;}public event EventHandler CanExecuteChanged;public bool CanExecute(object parameter){return this.owner.ContactsView.CurrentItem != null;}public void Execute(object parameter){this.owner.ShowDetails = (bool)parameter;}public void RaiseCanExecuteChanged(){var handler = this.CanExecuteChanged;if (handler != null){handler(this, EventArgs.Empty);}}}#endregion}復制代碼

(三)在SendMessageModel.cs

復制代碼//Notification介紹//(1)Notification類支持普通交互請求服務//(2)Notification類是作為對象上下文最基本得類//(3)用于交互請求時通知用戶。//(4)提供了兩個屬性Title和Content被顯示給用戶//(5)通常,通知是單向的,所以Notification在交互期間不能預測用戶將會改變Title和Content//(6)Confirmation類繼承自Notification類和添加了第三個屬性Cofirmed--被用于表示用戶已經確認或者拒絕操作//(7)Confirmation類用于實現MessageBox樣式交互,當用戶想獲取yes/no相應從呼呼那里。//(8)你自定一個上下文類繼承自Notification封裝成無論是支持交互的數據還是狀態你需要public class SendMessageViewModel : Notification, INotifyPropertyChanged{private readonly Contact contact;private readonly ChatViewModel parent;private bool? result;private string message;public SendMessageViewModel(Contact contact, ChatViewModel parent){this.contact = contact;this.parent = parent;}public Contact Contact{get { return this.contact; }}public string Message{get{return this.message;}set{if (value != this.message){this.message = value; RaisePropertyChanged(() => this.Message);}}}public bool? Result{get{return this.result;}set{if (value != this.result){this.result = value;RaisePropertyChanged(() => this.Result);}}}public event PropertyChangedEventHandler PropertyChanged;protected virtual void OnPropertyChanged(string propertyName){PropertyChangedEventHandler handler = PropertyChanged;if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));}private void RaisePropertyChanged<T>(Expression<Func<T>> lambda){var name = PropertySupport.ExtractPropertyName<T>(lambda);OnPropertyChanged(name);}}復制代碼

(四)在Infrastructure文件夾下的ViewModel.cs代碼如下:

復制代碼/// <summary>/// Base class for view models./// </summary>/// <remarks>/// This class provides basic support for implementing the <see cref="INotifyPropertyChanged"/> interface./// </remarks>public class ViewModel : INotifyPropertyChanged{/// <summary>/// Raised when a property on this object has a new value./// </summary>public event PropertyChangedEventHandler PropertyChanged;/// <summary>/// Raises this object's PropertyChanged event./// </summary>/// <typeparam name="T">The type of the property that has a new value</typeparam>/// <param name="propertyExpresssion">A Lambda expression representing the property that has a new value.</param>protected void RaisePropertyChanged<T>(Expression<Func<T>> propertyExpresssion){var propertyName = PropertySupport.ExtractPropertyName(propertyExpresssion);this.RaisePropertyChanged(propertyName);}/// <summary>/// Raises this object's PropertyChanged event./// </summary>/// <param name="propertyName">The property that has a new value.</param>protected virtual void RaisePropertyChanged(string propertyName){var handler = this.PropertyChanged;if (handler != null){handler(this, new PropertyChangedEventArgs(propertyName));}}protected void ExecuteOnUIThread(Action action){var dispatcher = Deployment.Current.Dispatcher;if (dispatcher.Checkaccess()){action();}else{dispatcher.BeginInvoke(action);}}}復制代碼

(五)在Infrastructure文件夾下的Behavior文件夾下,有自己定義行為(Behavior)和操作(Action)

(1) RelocatePopupBehavior行為類

復制代碼//該自定義行為:確保彈出串口定位在父視圖的右下角/// <summary>/// Behavior that ensures a popup is located at the bottom-right corner of its parent./// </summary>public class RelocatePopupBehavior : Behavior<Popup>{protected override void OnAttached(){base.OnAttached();this.AssociatedObject.Opened += this.OnPopupOpened;this.AssociatedObject.Closed += this.OnPopupClosed;}protected override void OnDetaching(){this.AssociatedObject.Opened -= this.OnPopupOpened;this.AssociatedObject.Closed -= this.OnPopupClosed;this.DetachSizeChangeHandlers();base.OnDetaching();}private void OnPopupOpened(object sender, EventArgs e){this.UpdatePopupOffsets();this.AttachSizeChangeHandlers();}private void OnPopupClosed(object sender, EventArgs e){this.DetachSizeChangeHandlers();}private void AttachSizeChangeHandlers(){var child = this.AssociatedObject.Child as FrameworkElement;if (child != null){child.SizeChanged += this.OnChildSizeChanged;}var parent = this.AssociatedObject.Parent as FrameworkElement;if (parent != null){parent.SizeChanged += this.OnParentSizeChanged;}}private void DetachSizeChangeHandlers(){var child = this.AssociatedObject.Child as FrameworkElement;if (child != null){child.SizeChanged -= this.OnChildSizeChanged;}var parent = this.AssociatedObject.Parent as FrameworkElement;if (parent != null){parent.SizeChanged -= this.OnParentSizeChanged;}}private void OnChildSizeChanged(object sender, EventArgs e){this.UpdatePopupOffsets();}private void OnParentSizeChanged(object sender, EventArgs e){this.UpdatePopupOffsets();}private void UpdatePopupOffsets(){if (this.AssociatedObject != null){var child = this.AssociatedObject.Child as FrameworkElement;var parent = this.AssociatedObject.Parent as FrameworkElement;if (child != null && parent != null){var anchor = new Point(parent.ActualWidth, parent.ActualHeight);this.AssociatedObject.HorizontalOffset = anchor.X - child.ActualWidth;this.AssociatedObject.VerticalOffset = anchor.Y - child.ActualHeight;}}}}復制代碼

(2) ShowNotificationAction.cs定義了行為

復制代碼/行為是功能單元容器。有兩種類型的行為//(1)不具有調用概念的行為,以附加的方式添加到對象上//(2)觸發器和動作更接近調用模型//你可以重復利用事件的句柄或者粗發起到UI上。namespace StateBasedNavigation.Infrastructure.Behaviors{//這個自定義行為允許ViewModel推一個通知到目標元素UI上,通過用戶接受在在右下角處 public class ShowNotificationAction : TargetedTriggerAction<FrameworkElement>{//注冊依賴屬性NotificationTimeoutPropertypublic static readonly DependencyProperty NotificationTimeoutProperty =DependencyProperty.Register("NotificationTimeout", typeof(TimeSpan), typeof(ShowNotificationAction), new PropertyMetadata(newTimeSpan(0, 0, 5)));private ObservableCollection<object> notifications;public ShowNotificationAction(){ this.notifications = new ObservableCollection<object>();}public TimeSpan NotificationTimeout{get { return (TimeSpan)GetValue(NotificationTimeoutProperty); }set { SetValue(NotificationTimeoutProperty, value); }}protected override void OnTargetChanged(FrameworkElement oldTarget, FrameworkElement newTarget){base.OnTargetChanged(oldTarget, newTarget);if (oldTarget != null){this.Target.ClearValue(FrameworkElement.DataContextProperty);}if (newTarget != null){this.Target.DataContext = this.notifications;}}protected override void Invoke(object parameter){var args = parameter as InteractionRequestedEventArgs;if (args == null){return;}var notification = args.Context;this.notifications.Insert(0, notification);var timer = new DispatcherTimer { Interval = this.NotificationTimeout };EventHandler timerCallback = null;timerCallback =(o, e) =>{timer.Stop();timer.Tick -= timerCallback;this.notifications.Remove(notification);};timer.Tick += timerCallback;timer.Start();args.Callback();}}}復制代碼

(七 )項目組織結構及運行截圖

    


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲人精品午夜在线观看| 欧美在线中文字幕| 亚洲最新av在线网站| 亚洲欧美精品一区| 亚洲日本中文字幕免费在线不卡| 在线播放精品一区二区三区| 97在线看免费观看视频在线观看| 亚洲精品久久久久中文字幕欢迎你| 国产精品爽黄69天堂a| 亚洲精品一区二区三区婷婷月| 亚洲日本中文字幕免费在线不卡| 欧美伊久线香蕉线新在线| 国产精品第3页| 精品国产欧美成人夜夜嗨| 日日狠狠久久偷偷四色综合免费| 国产婷婷色综合av蜜臀av| 国产精品久久久av久久久| 国产99久久精品一区二区 夜夜躁日日躁| 亚洲一区二区三区视频| 中文字幕日韩免费视频| 欧美在线观看日本一区| 欧美成人h版在线观看| 国产精品视频男人的天堂| 91精品国产高清久久久久久久久| 亚洲视频在线观看视频| 69精品小视频| 日韩av一区在线| 成人免费观看网址| 欧美性猛交xxxx富婆弯腰| 日韩av电影手机在线观看| 久久99亚洲精品| 亚洲色在线视频| 日韩av有码在线| 欧美国产精品日韩| 亚洲国产成人精品久久久国产成人一区| 日韩欧美在线视频日韩欧美在线视频| 国产成人精品电影久久久| 中文在线不卡视频| 欧美成人中文字幕在线| 国产精品久久久久久久久久尿| 国产精品成人久久久久| 久久精品人人爽| 国产精品成人av在线| 成人网址在线观看| 国产精品久久久久久一区二区| 久久精品国产清自在天天线| 亚洲精品福利资源站| 日韩av在线网站| 国产精品美乳在线观看| 欧美日韩亚洲一区二区| 亚洲天堂成人在线| 日韩国产激情在线| 91精品视频在线免费观看| 日韩成人黄色av| 亚洲精品一区久久久久久| 久久久97精品| 久久久久久亚洲精品中文字幕| 国产精品久久久久久影视| 欧美激情一级精品国产| 国外成人在线视频| 色综合久久88色综合天天看泰| 精品综合久久久久久97| 欧美日韩国产在线看| 欧美精品亚州精品| 日韩av快播网址| 国产在线视频欧美| 亚洲成年人在线| 中文字幕欧美专区| 亚洲欧美精品在线| 中文字幕日韩在线观看| 国内精品在线一区| 国产日韩综合一区二区性色av| 日韩在线中文字幕| 欧美成人sm免费视频| 色噜噜狠狠狠综合曰曰曰88av| 91精品国产91久久久久久不卡| 日韩高清人体午夜| 69久久夜色精品国产69乱青草| 国产亚洲精品91在线| 久久99国产精品久久久久久久久| 色婷婷久久一区二区| 欧美午夜激情视频| 亚洲欧洲国产一区| 国产精品偷伦视频免费观看国产| 欧美一区在线直播| 日韩在线播放av| 欧美午夜视频一区二区| 美女视频黄免费的亚洲男人天堂| 亚洲成人性视频| 国产精品手机播放| 91精品久久久久久久久| 日韩免费黄色av| 亚洲一区中文字幕| 成人激情视频在线播放| 91久久精品久久国产性色也91| 国产精品人成电影| 亚洲成av人影院在线观看| 亚洲精品国偷自产在线99热| 色视频www在线播放国产成人| 欧美大片在线看| 欧美日本啪啪无遮挡网站| 欧美一级淫片丝袜脚交| 日韩中文字幕视频在线观看| 国产亚洲欧美日韩精品| 欧美一区二区三区免费观看| 国产精品黄页免费高清在线观看| 亚洲国产精久久久久久| 2020久久国产精品| 91精品久久久久久久久中文字幕| 亚洲美女免费精品视频在线观看| 韩国精品久久久999| 欧美成年人视频网站| 亚洲性生活视频在线观看| 欧美猛交ⅹxxx乱大交视频| 国产精品igao视频| 久久人91精品久久久久久不卡| 欧美高清激情视频| 国产+人+亚洲| 日韩欧美在线国产| 亚洲欧美制服丝袜| 亚洲国产日韩精品在线| 国产精品久久999| 国产精品久久久精品| 国产激情999| 久久影视电视剧免费网站清宫辞电视| 亚洲美女在线视频| 日韩欧美精品网站| 91精品国产91久久久久久最新| 91沈先生作品| 亚洲最大激情中文字幕| 久久免费精品日本久久中文字幕| 久久天堂av综合合色| 亚洲精品成a人在线观看| 黄色91在线观看| 亚洲精品国产美女| 亚洲女同性videos| 久久69精品久久久久久久电影好| 国产精品爽爽爽爽爽爽在线观看| 少妇激情综合网| 亚洲精品有码在线| 亚洲人成网站免费播放| 成人黄色片网站| 日韩在线观看网址| 另类专区欧美制服同性| 久久久久久久一区二区三区| 成人久久久久爱| 久久久久久久999| 成人精品一区二区三区电影黑人| 综合136福利视频在线| 57pao国产精品一区| 欧美成人久久久| 98精品在线视频| 欧美日韩国产精品一区| 日韩av免费看网站| 国产精品白丝jk喷水视频一区| 久久久精品美女| 日韩中文在线中文网三级| 一区二区三区久久精品| 欧美激情第6页| 日韩黄色高清视频| 国产精品久久一区主播| 中文字幕精品国产| yellow中文字幕久久| 国产va免费精品高清在线观看|