08Prism WPF 入门实战 - Cmd&EeventAggregator
概要
1.Command
(1)Commnad命令
命令表示应用程序任务,并且跟踪任务是否能够被执行。在Prism里Command相关的对象都被集成到Prism框架中(namespace Prism.Commands)方便开发者使用。
命令的使用分为4个步骤。
(1)VM层定义命令(带参命令则需要在命令的尖括号内指定参数类型)
(2)View层绑定命令
(3)指定命令源
(4)指定执行命令的控件
详细内容
command的定义。
private DelegateCommand _printMsg1Command;
public DelegateCommand PrintMsg1Command { get => _printMsg1Command ?? (_printMsg1Command = new DelegateCommand(PrintMsgAction)); }
实现command需要执行的内容。
private void PrintMsgAction()
{
Debug.WriteLine("hello,word.");
}
view.xaml中调用
<Button Width="150" Height="30" Content="PrintCommand" Command="{Binding PrintMsg1Command}"></Button>
(2)CompositeCommand(复合命令)的作用为执行一组Command。
命令的使用分为5个步骤。
(1)VM层定义复合命令以及命令
(2)将命令注册到复合命令中
(3)View层绑定命令
(4)指定命令源
(5)指定执行命令的控件
详细内容
定义并实现需要被组合的command。
private DelegateCommand _printMsg1Command;
private DelegateCommand _printMsg2Command;
public DelegateCommand PrintMsg1Command { get => _printMsg1Command ?? (_printMsg1Command = new DelegateCommand(PrintMsgAction1)); }
public DelegateCommand PrintMsg2Command { get => _printMsg2Command ?? (_printMsg2Command = new DelegateCommand(PrintMsgAction2)); }
private void PrintMsgAction1()
{
Debug.WriteLine("hello,word1.");
}
private void PrintMsgAction2()
{
Debug.WriteLine("hello,word2.");
}
定义组合命令
public CompositeCommand TempCompoCommand { get => _tempCompoCommand ?? (_tempCompoCommand = new CompositeCommand()); }
//初始化组合命令
public MainWindowViewModel()
{
TempCompoCommand.RegisterCommand(PrintMsg1Command);
TempCompoCommand.RegisterCommand(PrintMsg2Command);
}
view.xaml中调用
<Button Width="150" Height="30" Content="CompoCommand" Command="{Binding TempCompoCommand}"></Button>
2.EventAggregator
EventAggregator(聚合事件),在Prism框架当中是单独的一层;例如:可用于View或Module之间做消息通知(传值)。它是由PubSubEvent<T>和IEventAggregator支撑。
聚合事件的使用分为2块。
(1)发布消息
(2)订阅消息
详细内容
- Prism中聚合事件的定义。
namespace Prism.Events
{
//
// 摘要:
// Defines a class that manages publication and subscription to events.
//
// 类型参数:
// TPayload:
// The type of message that will be passed to the subscribers.
public class PubSubEvent<TPayload> : EventBase
{
//
// 摘要:
// Subscribes a delegate to an event that will be published on the Prism.Events.ThreadOption.PublisherThread.
// Prism.Events.PubSubEvent`1 will maintain a System.WeakReference to the target
// of the supplied action delegate.
//
// 参数:
// action:
// The delegate that gets executed when the event is published.
//
// 返回结果:
// A Prism.Events.SubscriptionToken that uniquely identifies the added subscription.
//
// 言论:
// The PubSubEvent collection is thread-safe.
public SubscriptionToken Subscribe(Action<TPayload> action)
{
return Subscribe(action, ThreadOption.PublisherThread);
}
//
// 摘要:
// Subscribes a delegate to an event that will be published on the Prism.Events.ThreadOption.PublisherThread
//
// 参数:
// action:
// The delegate that gets executed when the event is raised.
//
// filter:
// Filter to evaluate if the subscriber should receive the event.
//
// 返回结果:
// A Prism.Events.SubscriptionToken that uniquely identifies the added subscription.
public virtual SubscriptionToken Subscribe(Action<TPayload> action, Predicate<TPayload> filter)
{
return Subscribe(action, ThreadOption.PublisherThread, keepSubscriberReferenceAlive: false, filter);
}
//
// 摘要:
// Subscribes a delegate to an event. PubSubEvent will maintain a System.WeakReference
// to the Target of the supplied action delegate.
//
// 参数:
// action:
// The delegate that gets executed when the event is raised.
//
// threadOption:
// Specifies on which thread to receive the delegate callback.
//
// 返回结果:
// A Prism.Events.SubscriptionToken that uniquely identifies the added subscription.
//
// 言论:
// The PubSubEvent collection is thread-safe.
public SubscriptionToken Subscribe(Action<TPayload> action, ThreadOption threadOption)
{
return Subscribe(action, threadOption, keepSubscriberReferenceAlive: false);
}
//
// 摘要:
// Subscribes a delegate to an event that will be published on the Prism.Events.ThreadOption.PublisherThread.
//
// 参数:
// action:
// The delegate that gets executed when the event is published.
//
// keepSubscriberReferenceAlive:
// When true, the Prism.Events.PubSubEvent`1 keeps a reference to the subscriber
// so it does not get garbage collected.
//
// 返回结果:
// A Prism.Events.SubscriptionToken that uniquely identifies the added subscription.
//
// 言论:
// If keepSubscriberReferenceAlive is set to false, Prism.Events.PubSubEvent`1 will
// maintain a System.WeakReference to the Target of the supplied action delegate.
// If not using a WeakReference (keepSubscriberReferenceAlive is true), the user
// must explicitly call Unsubscribe for the event when disposing the subscriber
// in order to avoid memory leaks or unexpected behavior.
// The PubSubEvent collection is thread-safe.
public SubscriptionToken Subscribe(Action<TPayload> action, bool keepSubscriberReferenceAlive)
{
return Subscribe(action, ThreadOption.PublisherThread, keepSubscriberReferenceAlive);
}
//
// 摘要:
// Subscribes a delegate to an event.
//
// 参数:
// action:
// The delegate that gets executed when the event is published.
//
// threadOption:
// Specifies on which thread to receive the delegate callback.
//
// keepSubscriberReferenceAlive:
// When true, the Prism.Events.PubSubEvent`1 keeps a reference to the subscriber
// so it does not get garbage collected.
//
// 返回结果:
// A Prism.Events.SubscriptionToken that uniquely identifies the added subscription.
//
// 言论:
// If keepSubscriberReferenceAlive is set to false, Prism.Events.PubSubEvent`1 will
// maintain a System.WeakReference to the Target of the supplied action delegate.
// If not using a WeakReference (keepSubscriberReferenceAlive is true), the user
// must explicitly call Unsubscribe for the event when disposing the subscriber
// in order to avoid memory leaks or unexpected behavior.
// The PubSubEvent collection is thread-safe.
public SubscriptionToken Subscribe(Action<TPayload> action, ThreadOption threadOption, bool keepSubscriberReferenceAlive)
{
return Subscribe(action, threadOption, keepSubscriberReferenceAlive, null);
}
//
// 摘要:
// Subscribes a delegate to an event.
//
// 参数:
// action:
// The delegate that gets executed when the event is published.
//
// threadOption:
// Specifies on which thread to receive the delegate callback.
//
// keepSubscriberReferenceAlive:
// When true, the Prism.Events.PubSubEvent`1 keeps a reference to the subscriber
// so it does not get garbage collected.
//
// filter:
// Filter to evaluate if the subscriber should receive the event.
//
// 返回结果:
// A Prism.Events.SubscriptionToken that uniquely identifies the added subscription.
//
// 言论:
// If keepSubscriberReferenceAlive is set to false, Prism.Events.PubSubEvent`1 will
// maintain a System.WeakReference to the Target of the supplied action delegate.
// If not using a WeakReference (keepSubscriberReferenceAlive is true), the user
// must explicitly call Unsubscribe for the event when disposing the subscriber
// in order to avoid memory leaks or unexpected behavior. The PubSubEvent collection
// is thread-safe.
public virtual SubscriptionToken Subscribe(Action<TPayload> action, ThreadOption threadOption, bool keepSubscriberReferenceAlive, Predicate<TPayload> filter)
{
IDelegateReference actionReference = new DelegateReference(action, keepSubscriberReferenceAlive);
IDelegateReference filterReference = (filter == null) ? new DelegateReference((Predicate<TPayload>)((TPayload _003Cp0_003E) => true), keepReferenceAlive: true) : new DelegateReference(filter, keepSubscriberReferenceAlive);
EventSubscription<TPayload> eventSubscription;
switch (threadOption)
{
case ThreadOption.PublisherThread:
eventSubscription = new EventSubscription<TPayload>(actionReference, filterReference);
break;
case ThreadOption.BackgroundThread:
eventSubscription = new BackgroundEventSubscription<TPayload>(actionReference, filterReference);
break;
case ThreadOption.UIThread:
if (base.SynchronizationContext == null)
{
throw new InvalidOperationException(Resources.EventAggregatorNotConstructedOnUIThread);
}
eventSubscription = new DispatcherEventSubscription<TPayload>(actionReference, filterReference, base.SynchronizationContext);
break;
default:
eventSubscription = new EventSubscription<TPayload>(actionReference, filterReference);
break;
}
return InternalSubscribe(eventSubscription);
}
//
// 摘要:
// Publishes the Prism.Events.PubSubEvent`1.
//
// 参数:
// payload:
// Message to pass to the subscribers.
public virtual void Publish(TPayload payload)
{
InternalPublish(payload);
}
//
// 摘要:
// Removes the first subscriber matching System.Action`1 from the subscribers' list.
//
// 参数:
// subscriber:
// The System.Action`1 used when subscribing to the event.
public virtual void Unsubscribe(Action<TPayload> subscriber)
{
lock (base.Subscriptions)
{
IEventSubscription eventSubscription = base.Subscriptions.Cast<EventSubscription<TPayload>>().FirstOrDefault((EventSubscription<TPayload> evt) => evt.Action == subscriber);
if (eventSubscription != null)
{
base.Subscriptions.Remove(eventSubscription);
}
}
}
//
// 摘要:
// Returns true if there is a subscriber matching System.Action`1.
//
// 参数:
// subscriber:
// The System.Action`1 used when subscribing to the event.
//
// 返回结果:
// true if there is an System.Action`1 that matches; otherwise false.
public virtual bool Contains(Action<TPayload> subscriber)
{
IEventSubscription eventSubscription;
lock (base.Subscriptions)
{
eventSubscription = base.Subscriptions.Cast<EventSubscription<TPayload>>().FirstOrDefault((EventSubscription<TPayload> evt) => evt.Action == subscriber);
}
return eventSubscription != null;
}
}
}
- 定义消息传递参数Model
public class TempEventModel
{
public string MessageType { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
- 定义消息事件
/// <summary>
/// 消息事件
/// </summary>
public class MessagerEvent : PubSubEvent<TempEventModel> //PubSubEvent<string>
{
}
- 定义聚合事件(订阅方)。
private IEventAggregator _eventAggregator;
public ContactViewModel(IEventAggregator eventAggregator)
{
//获取框架内聚合事件的引用
_eventAggregator = eventAggregator;
}
//初始化订阅
_eventAggregator.GetEvent<MessagerEvent>().Subscribe(OnSubscribeMessage,false);
//实现订阅回调(聚合事件被触发时需要执行的内容)
private void OnSubscribeMessage(TempEventModel eventModel)
{
//输出接收到的消息内容
Debug.WriteLine($" Wemail.Contact receive message : { eventModel.Name },{ eventModel.Age }.");
}
- 定义聚合事件(发送方)。
private IEventAggregator _eventAggregator;
public MainWindowViewModel(IEventAggregator eventAggregator)
{
_eventAggregator = eventAggregator;
}
//发布消息
_eventAggregator.GetEvent<MessagerEvent>().Publish(eventModel);
EventAggregator还有取消订阅、消息过滤功能。
取消订阅:是为了管理pub/sub特性所占用的资源,富客户端应用随着业务、时间的变化而复杂。极大的可能会导致客户端里穿插上百个消息,会导致代码非常混乱。所以在代码中慎用pub/sub这个特性,或及时取消不用的订阅因为这套机制存在强引用关系不会随着作用域的结束而结束(GC无法回收),如果任由发展会导致客户端内存上涨;解决这个问题除了及时取消订阅,还可以在订阅时指定keepSubcriberReferenceAlive参数为false。
消息过滤:也是管理pub/sub的手段之一,通过指定特定的消息类型来细化区分pub/sub消息传递。
- 定义聚合事件(订阅方)。
private IEventAggregator _eventAggregator;
public ContactViewModel(IEventAggregator eventAggregator)
{
//获取框架内聚合事件的引用
_eventAggregator = eventAggregator;
}
//初始化订阅
_eventAggregator.GetEvent<MessagerEvent>().Subscribe(OnSubscribeMessage,
ThreadOption.PublisherThread,false, MessageFilter);
//实现订阅回调(聚合事件被触发时需要执行的内容)
private bool MessageFilter(TempEventModel eventModel)
{
if (eventModel.MessageType == MessagerType.JusterMessage) return true;
return false;
}
- 定义聚合事件(发送方)。
private IEventAggregator _eventAggregator;
public MainWindowViewModel(IEventAggregator eventAggregator)
{
_eventAggregator = eventAggregator;
}
//发布消息
_eventAggregator.GetEvent<MessagerEvent>().Publish(eventModel);
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步