代码改变世界

MvvMLight学习心得一

2012-06-27 14:37  爱研究源码的javaer  阅读(1098)  评论(0编辑  收藏  举报

最近兴起,对WPF MVVMLight学习研究,MVVMLight官方网站http://galasoft.ch/mvvm/,是MVVMLight作者的网

站,你可以在此网站上下载到WPF MVVMLight的最新版本,了解它的最新消息。

关于MVVMLight的其他信息及资料,我就不多说了,你可以参考国内的一些网站,如博客园http://www.cnblogs.com

等。

首先你需要在项目中添加对MVVMLight程序集的引用:

image

随后你需要在项目中添加两个文件夹以区分View和ViewModel

image

在MainWindow.xaml.cs里加上DataContext:

this.DataContext = new MainViewModel();

这样就把MainWindow.xaml中的命令与MainViewModel中的属性关联了起来。

public class MainViewModel:ViewModelBase
{
    public MainViewModel()
    {
        Messenger.Default.Register<GenericMessage<string>>(this, "Save", msg =>
            {
                var message = msg.Content;
                MessageBox.Show(message);
            });
    }

    public ICommand SaveCommand
    {
        get
        {
            return new RelayCommand(() =>
                {
                    Messenger.Default.Send<GenericMessage<string>>(new GenericMessage<string>("Hello,World"), "Save");
                });
        }
     }

MainViewModel继承自GalaSoft.MvvmLight,需在类顶部添加它的命名空间

using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Messaging;

你可以看到MainViewModel构造函数里注册了一个GalaSoft的一个回调消息。MainViewModel里又定义了一个

SaveCommand属性返回GalaSoft的RelayCommand对象。

我们看看前台界面MainWindow.xaml是怎样的:

<Window x:Class="John.WPF.View.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="300" Width="300">
    <Grid>
        <Button Command="{Binding SaveCommand}" Content="点击我" />
    </Grid>
</Window>

很简单吧,就加了个Button,再定义了Command属性,再绑定MainViewModel里的SaveCommand.

启动项目后我们点击Button按钮,就会弹出我们在MainViewModel构造函数里注册的回调消息。

var message = msg.Content;
MessageBox.Show(message);

接下来我们逐步剖析,首先看看ViewModelBase类:

public abstract class ViewModelBase : INotifyPropertyChanged, ICleanup, IDisposable
{
    protected ViewModelBase();
    protected ViewModelBase(IMessenger messenger);

    [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "Non static member needed for data binding")]
    public bool IsInDesignMode { get; }
    [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "The security risk here is neglectible.")]
    public static bool IsInDesignModeStatic { get; }
    protected IMessenger MessengerInstance { get; set; }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void Broadcast<T>(T oldValue, T newValue, string propertyName);
    public virtual void Cleanup();
    public void Dispose();
    [Obsolete("This interface will be removed from ViewModelBase in a future version, use ICleanup.Cleanup instead.")]
    protected virtual void Dispose(bool disposing);
    [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate", Justification = "This cannot be an event")]
    protected virtual void RaisePropertyChanged(string propertyName);
    [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate", Justification = "This cannot be an event")]
    protected virtual void RaisePropertyChanged<T>(string propertyName, T oldValue, T newValue, bool broadcast);
    [Conditional("DEBUG")]
    [DebuggerStepThrough]
    public void VerifyPropertyName(string propertyName);
}

可以看到ViewModelBase是个抽象类。还有个带参数的构造函数,它帮我们实现了很多接口。

再看看Messager类:

public Messenger();

public static Messenger Default { get; }

public static void OverrideDefault(Messenger newMessenger);
public virtual void Register<TMessage>(object recipient, Action<TMessage> action);
public virtual void Register<TMessage>(object recipient, bool receiveDerivedMessagesToo, Action<TMessage> action);
public virtual void Register<TMessage>(object recipient, object token, Action<TMessage> action);
public virtual void Register<TMessage>(object recipient, object token, bool receiveDerivedMessagesToo, Action<TMessage> action);
public static void Reset();
[SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "This syntax is more convenient than other alternatives.")]
public virtual void Send<TMessage, TTarget>(TMessage message);
public virtual void Send<TMessage>(TMessage message);
public virtual void Send<TMessage>(TMessage message, object token);
[SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "The type parameter TMessage identifies the message type that the recipient wants to unregister for.")]
public virtual void Unregister<TMessage>(object recipient);
public virtual void Unregister(object recipient);
public virtual void Unregister<TMessage>(object recipient, Action<TMessage> action);
要熟悉这两个类帮我们做了哪些事情,需要对源码进行剖析。下回再说吧。