您的位置:首页 > 其它

MVVMLight源码分析之消息机制和ViewModelBase

2010-11-06 18:24 337 查看
目录

1 介绍 MVVMLight

2 代码分析方法

3 具体剖析

3.1 消息机制的剖析

3.2 ViewModelBase

3.3 Command 介绍/EventToCommand behavior

3.4 DispatcherHelper

1介绍MVVMLight

试用范围: 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.
==

2代码分析方法

2.1 按照骑士的建议,先从测试代码看起。完整了解其功能。

2.2 使用类图看其结构。

3.3 顾名思义+debug看其执行。

之前我还去TOPLANGUAGE整理了一下牛牛们的想法,也一并贴出来供大家参考。排版乱抱歉。

荣耀属于TOPLANGUAGE

1

画UML. 由表及里,由浅入深,由轮廓到详细。 画完了也就分析的八九不离十了。 这个过程需要经验的积累。。刚开始会比较难,后来会越顺手。

2我感觉自己看的效率还是比较高,也是喜欢看底层,弄明白每个类干什么的,除非源码不可见。刚开始看时不去理会每个类的具体实现,而

毕竟

代码是是从入口(比如一个库暴露的比较重要的API)一层一层往里看,先理清那些主要的类之间的调用关系,在脑力里大致形成了一张类关系图之后再看实现细节。在源码不可见的情况下,通过它们暴露的接口组合也基本能猜出里边的一些实现机制(是猜测,不一定正确了).

3

先考虑一个模块
a,打开class view,根据class name 来判断这个类的功能。在心里对每一个类功能,已经类之间的相互关系有一个底。
想想如果你是这模块的设计者,你应该怎么去设计?一般来说,有经验的程序员代码都会按照MVC模式去设计代码,
并且每一个类的功能都会非常简洁。
b,读class,先看私有变量,一个class中哪些数据,这是一个class的核心,大部分操作都是相对数据来操作的。
然后看接口。

模块之间耦合
如果你是设计者你应该怎么去设计?比如要你来设计3D游戏引擎?站在设计者的角度,用设计者的思维去多考虑问题。

4 有本书叫做code reading。

5 divide and conquer

6

我倒是读过十来万行的服务端软件的代码,不过说十多万行,其实我看的也就很小一部分。成熟、设计良好的软件,其主干脉络很清晰的。
从入口开始,看其初始化过程,可以基本上把握其内部的各类数据结构以及其之间的关系。
初始化过程之后,如果面向过程的代码,就找其主体逻辑;如果事件驱动的,就找其事件分发部分的代码

最怕的看面向接口编程的带有动态特性的代码,一大堆的接口和ioc,有的时候不用调试方式跑起来看内存根本就不知道具体实例对应的哪个类。

整个过程由于入口到真正核心部分代码的分支可能会有很多,所以这一个不断地探路、回溯的过程。推荐用一段大块、整段的时间去看代码,这样不至于下回看
的时候就忘记了。

7First of all, you must have a clear understanding about the business logic,
then you can jump in the code.

8

1.jinq0123,supern lee——规范写代码,通过名称来了解类、变量、方法的含义。

2.Alan GAO——通过画UML图,了解软件结构。
3.云端孤鹜——通过类提供的接口,判断其是否重要,进而深入了解。
4.Michael——站在模块功能设计的角度上来了解,具体类里面先看私有变量,然后看接口。
5.sagasw——有本书叫code reading.找感兴趣的部分去读,然后外延,熟能生巧。读别人的设计文档或者看那些读代码的书。
6.机械唯物主义——逐个击破。
7.Weiming
Yin——(看法和我类似)根据软件的运行逻辑,从main开始看,不断延伸,通过打印信息跟踪观察,利用优秀编辑工具能够快速阅读代码。有些地方自己思考后发 现没有难度,可以粗略过,如果有些地方设计到多态或者分支,则需要研读,并延伸到它的数据结构。
8.Tiny fool——勇敢的移植代码学习者。
9.Kenny Yuan——规范和结构显得无比重要,大工程是无法掌握的。
10.Linker——看不懂代码的地方最好走人。(我相信你这么说是认为我们公司缺乏代码规范,不适合发展,其实也不是,就算公司再规范,也不是说就可以轻易 看懂代码的。还是要感谢你的关心,不过我会继续坚持下去的。)

9

最近刚好看了一个基于业务的C++面向对象的大型代码,说说我自己的感受吧

代码量大概在5w行上下,全部是实现业务,底层封装全部有公司自己的基础类实现了,包括main()函数。。。

我的习惯是首先把大的框架搞懂,明白这个代码的流程是怎样的,大块的功能是什么,如果直接看代码细节的话,会看的不知所以然,看完大体功能,大致就可以知道这个 程序是干嘛的了,然后再去钻研里面的细节。

最重要的是做阅读笔记了,写写流程,把自己的理解写下来。

大量的代码,看了肯定就会忘的,有笔记以后再复习就方便了
对于有大量基础实现的东西,可能不适应,我也没有这方面的经验。

3具体剖析

打开源码我们可以看到

实现执行发送的代码 /// <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))]
public class WeakAction<T> : WeakAction, IExecuteWithObject
{
private readonly 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>
public new 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>
public new void 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>
public void 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>
public void 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>
public virtual void Unregister<TMessage>(object recipient, Action<TMessage> action) {
UnregisterFromLists(recipient, action, _recipientsStrictAction);
UnregisterFromLists(recipient, action, _recipientsOfSubclassesAction);
Cleanup();
}

提一下 Cleanup();

这个函数的一个作用就是当GC回收了弱引用的对象,他就负责将其清除出列表。

ViewModelBase

他的VIEWMODEL只有一个。没有更多派生类。

其中几个就是下面。

VIEWMODELIsInDesignMode 是否在设计模式之下

VerifyPropertyName 验证属性是否出错

//封装了 消息的操作

Broadcast 发送属性改变。即消息发送。

继承自 ICleanup 接口的 Cleanup (); 取消

//

其中不少思想都在John Gossman的文章中就有体现了。其中的RelayCommand就是直接在其文中就有。强推此文。

其他的下次有时间再说。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: