试用范围:Windows Presentation Foundation, Silverlight and for Windows Phone 7
作者的介绍
The GalaSoft.MvvmLight library with helper classes:
A ViewModelBase class to be used as the base class for ViewModels.
A Messenger class (and diverse message types) to be used to communicate within the application. Recipients only receive the message types that they register for. Additionally, a target type can be specified, in which case the message will only be transmitted if the recipient's type matches the target parameter. Messages can be anything from simple values to complex objects. You can also use specialized message types, or create your own types deriving from them. More information about the Messenger class.
MessageBase: A simple message class, carrying optional information about the message's sender.
GenericMessage<T>: A simple message with a Content property of type T.
NotificationMessage: Used to send a notification (as a string) to a recipient. For example, save your notifications as constant in a Notifications class, and then send Notifications.Save to a recipient.
NotificationMessage<T>: Same as above, but with a generic Content property. Can be used to pass a parameter to the recipient together with the notification.
NotificationMessageAction: Sends a notification to a recipient and allows the recipient to call the sender back.
NotificationMessageAction<T>: Sends a notification to a recipient and allows the recipient to call the sender back with a generic parameter.
DialogMessage: Used to request that a recipient (typically a View) displays a dialog, and passes the result back to the caller (using a callback). The recipient can choose how to display the dialog, either with a standard MessageBox, with a custom popup, etc…
PropertyChangedMessage<T>: Used to broadcast that a property changed in the sender. Fulfills the same purpose than the PropertyChanged event, but in a less tight way.
Command classes optimized for WPF and Silverlight and simplifying commanding in your application. Available with or without generic parameter (RelayCommand<T> and RelayCommand). For an in-depth analysis, I encourage you to read Using RelayCommands in Silverlight and WPF
The GalaSoft.MvvmLight.Extras library with optional classes:
EventToCommand behavior, allowing you to bind any event of any UI element to an ICommand, for example on the ViewModel, directly in XAML. This makes using Commands much easier, without writing code behind. With the newest version, you can even get the EventArgs of the fired event directly in the ViewModel to handle it.
DispatcherHelper class, a lightweight class helping you to create multithreaded applications.
///<summary> /// Registers a recipient for a type of message TMessage. /// 为T类型的参数 注册一个接受者, /// The action parameter will be executed when a corresponding (相应的) /// (当接收到) 参数action 这个方法将被执行 /// message is sent. See the receiveDerivedMessagesToo parameter /// for details on how messages deriving from TMessage (or, if TMessage is an interface, /// messages implementing TMessage) can be received too. /// 是否 接收 接口的 派生类的 信息 ///<para>Registering a recipient does not create a hard reference to it, /// so if this recipient is deleted, no memory leak is caused.</para> ///</summary> ///<typeparam name="TMessage">The type of message that the recipient registers /// for.</typeparam> ///<param name="recipient">The recipient that will receive the messages.</param> ///<param name="token">A token(标记) for a messaging channel. /// token 是一个 栏目的标记 /// If a recipient registers /// using a token, and a sender sends a message using the same token, then this /// 发送和接收方使用同一个标记 token接收 才能 接收到 /// message will be delivered to the recipient. Other recipients who did not /// /// use a token when registering (or who used a different token) will not /// get the message. /// /// Similarly, messages sent without any token, or with a different /// token, will not be delivered to that recipient.</param> /// ///<param name="receiveDerivedMessagesToo">If true, message types deriving from /// TMessage will also be transmitted to the recipient. For example, if a SendOrderMessage /// and an ExecuteOrderMessage derive from OrderMessage, registering for OrderMessage /// and setting receiveDerivedMessagesToo to true will send SendOrderMessage /// and ExecuteOrderMessage to the recipient that registered. /// ///<para>Also, if TMessage is an interface, message types implementing TMessage will also be /// transmitted to the recipient. For example, if a SendOrderMessage /// and an ExecuteOrderMessage implement IOrderMessage, registering for IOrderMessage /// and setting receiveDerivedMessagesToo to true will send SendOrderMessage /// and ExecuteOrderMessage to the recipient that registered.</para> ///</param> ///<param name="action">The action that will be executed when a message /// of type TMessage is sent.</param> publicvirtualvoid Register<TMessage>(//TMessage接收的 类型 object recipient,//接收的对象一般是viewmodel object token,//标记 ,细分类型下面的 分类。 bool receiveDerivedMessagesToo,// 是否也接收 (派生类的) 消息 Action<TMessage> action) {//当有消息来临的时候的 回调函数 var messageType =typeof(TMessage);
Dictionary<Type, List<WeakActionAndToken>> recipients; //============================ 是否也接收 (派生类的) 消息 if (receiveDerivedMessagesToo) { if (_recipientsOfSubclassesAction ==null) { _recipientsOfSubclassesAction =new Dictionary<Type, List<WeakActionAndToken>>(); }
if (!recipients.ContainsKey(messageType)) { //如果不存在 List 就添加 list =new List<WeakActionAndToken>(); recipients.Add(messageType, list); } else { list = recipients[messageType];//存在就取出 }
// 新建一个 weakAction 弱引用 方法 var weakAction =new WeakAction<TMessage>(recipient, action);// new WeakAction<TMessage>(viewmodel, function); var item =new WeakActionAndToken { Action = weakAction, Token = token }; list.Add(item);
//清除已经被垃圾回收的对象 Cleanup(); }
简单说明其各参数的意思。
public virtual void Register<TMessage>(//TMessage接收的 类型
if (_recipientsOfSubclassesAction !=null) { // Clone to protect from people registering in a "receive message" method // Bug correction Messaging BL0008.002 var listClone = _recipientsOfSubclassesAction.Keys.Take(_recipientsOfSubclassesAction.Count()).ToList();
foreach (var type in listClone) { List<WeakActionAndToken> list =null;
if (messageType == type || messageType.IsSubclassOf(type) || Implements(messageType, type)) { list = _recipientsOfSubclassesAction[type]; }
if (_recipientsStrictAction !=null) { if (_recipientsStrictAction.ContainsKey(messageType)) { var list = _recipientsStrictAction[messageType]; SendToList(message, list, messageTargetType, token); } }
Cleanup(); }
然后我们追到
privatestaticvoid SendToList<TMessage>( TMessage message, IEnumerable<WeakActionAndToken> list, Type messageTargetType, object
token) {
。。。。。。
executeAction.ExecuteWithObject(message);
。。。。。
}
最终实现的是
实现执行发送的代码
///<summary> /// Stores an Action without causing a hard reference to be created to the Action's owner. /// 为 拥有者 储存一个 方法 而不用 强引用 /// The owner can be garbage collected at any time. /// 而使得 拥有者(viewmodel)能在任意时候被 回收 ///</summary> ///<typeparam name="T">The type of the Action's parameter.</typeparam> ////[ClassInfo(typeof(Messenger))] publicclass WeakAction<T> : WeakAction, IExecuteWithObject { privatereadonly Action<T> _action;
///<summary> /// Initializes a new instance of the WeakAction class. ///</summary> ///<param name="target">The action's owner.</param> ///<param name="action">The action that will be associated to this instance.</param> public WeakAction(object target, Action<T> action) : base(target, null) { _action = action; }
///<summary> /// Gets the Action associated to this instance. ///</summary> publicnew Action<T> Action { get { return _action; } }
///<summary> /// Executes the action. This only happens if the action's owner /// is still alive. The action's parameter is set to default(T). ///</summary> publicnewvoid Execute() { if (_action !=null && IsAlive) { _action(default(T)); } }
///<summary> /// Executes the action. This only happens if the action's owner /// is still alive. ///</summary> ///<param name="parameter">A parameter to be passed to the action.</param> publicvoid Execute(T parameter) { if (_action !=null && IsAlive) { _action(parameter); } }
///<summary> /// Executes the action with a parameter of type object. This parameter /// will be casted to T. This method implements <see cref="IExecuteWithObject.ExecuteWithObject" /> /// and can be useful if you store multiple WeakAction{T} instances but don't know in advance /// what type T represents. ///</summary> ///<param name="parameter">The parameter that will be passed to the action after /// being casted to T.</param> publicvoid ExecuteWithObject(object parameter) { var parameterCasted = (T) parameter; Execute(parameterCasted); } }
这里牵扯到ACTION 和 T 的知识,不熟悉的可以自己去查一查。
然后是取消订阅这个比较简单 就是一个遍历然后从原来的列表中删除。
///<summary> /// Unregisters a message recipient for a given type of messages and for /// a given action. Other message types will still be transmitted to the /// recipient (if it registered for them previously). Other actions that have /// been registered for the message type TMessage and for the given recipient (if /// available) will also remain available. ///</summary> ///<typeparam name="TMessage">The type of messages that the recipient wants /// to unregister from.</typeparam> ///<param name="recipient">The recipient that must be unregistered.</param> ///<param name="action">The action that must be unregistered for /// the recipient and for the message type TMessage.</param> publicvirtualvoid Unregister<TMessage>(object recipient, Action<TMessage> action) { UnregisterFromLists(recipient, action, _recipientsStrictAction); UnregisterFromLists(recipient, action, _recipientsOfSubclassesAction); Cleanup(); }
原文地址:http://www.open-open.com/lib/view/open1346857871615.html
使用Java Mail API来发送邮件也很容易实现,但是最近公司一个同事封装的邮件API实在让我无法接受,于是便打算改用Spring Mail API来发送邮件,顺便记录下这篇文章。 【Spring Mail API】
Spring Mail API都在org.spri