【MVVMLight小记】一.快速搭建一个基于MVVMLight的silverlight小程序

  写了篇MVVM小记http://www.cnblogs.com/whosedream/p/mvvmnote1.html,说好要写点MVVMLight的东西,所以接着写,以便和大家共勉。

  我假设你已经有了MVVM的一些概念,那么我们就单刀直入了,怎样基于MVVMLight 来建项目呢?其实很简单,首先我们需要下载MVVMLight,然后安装,完了你会看到

Binaries里有各个版本的程序集

这里我用到了silverlight4的程序集

不过你安装了模板的话,新建模板项目,那么上面这些程序集就不用你手动去添加了,我用的是VS2012,所以安装了下面的第二个模板MvvmLight.VS2012.vsix

现在可以新建项目了,在新建项目silverlight选项里你会多看见2个选项

我用的是SL4那么我就选择第一个新建

我们可以看到一个大体的架子帮你搭出来了,按F5运行,会看到

 

 恭喜你的第一个MVVMLight应用完成了!!!让我们看看都写了些什么。

找到程序的入口App

<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
             x:Class="MvvmLightTest.App"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:vm="clr-namespace:MvvmLightTest.ViewModel"
             mc:Ignorable="d">
    <Application.Resources>
        <!--Global View Model Locator-->
        <vm:ViewModelLocator x:Key="Locator"
                             d:IsDataSource="True" />
    </Application.Resources>
</Application>

我们看到添加了个应用程序资源ViewModelLocator,这是干什么用的呢,下面再说,看看App.cs里写了些什么

  private void Application_Startup(object sender, StartupEventArgs e)
        {
            RootVisual = new MainPage();
            DispatcherHelper.Initialize();
        }

        private void Application_Exit(object sender, EventArgs e)
        {
            ViewModelLocator.Cleanup();
        }

和以前的代码相比,在程序退出里我们又看到了ViewModelLocator,看来这东西是贯穿我们应用程序始终的,待会再说。我们还发现在启动里多了个 DispatcherHelper.Initialize(),这是初始化什么的呢?

... 
public static void Initialize()
        {
            if (UIDispatcher == null)
            {
                UIDispatcher = Deployment.Current.Dispatcher;
            }
        }

   public static Dispatcher UIDispatcher
        {
            get;
            private set;
        }
...

看到了吗?它会获取当前应用程序的Dispatcher,Dispatcher是干什么用的?跨线程操作的时候你就会用到。

好了我们的程序RootVisual已经置了MainPage了,看看MainPage有什么

<UserControl x:Class="MvvmLightTest.MainPage"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:ignore="http://www.ignore.com"
             mc:Ignorable="d ignore"
             Height="300"
             Width="300"
             DataContext="{Binding  Main, Source={StaticResource Locator}}">

    <UserControl.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Skins/MainSkin.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </UserControl.Resources>

    <Grid x:Name="LayoutRoot">

        <TextBlock FontSize="36"
                   FontWeight="Bold"
                   Foreground="Purple"
                   Text="{Binding WelcomeTitle}"
                   VerticalAlignment="Center"
                   HorizontalAlignment="Center"
                   TextWrapping="Wrap" />

    </Grid>
</UserControl>

是不是还奇怪App里怎么MainPage没有对DataContext进行赋值,原来在这里

DataContext="{Binding  Main, Source={StaticResource Locator}}"

这里Locator是不是很熟悉,啊~对了,就是App的资源文件里添加的东西。现在我们来看看到底ViewModelLocator扮演着何方神圣。

 public class ViewModelLocator
    {
        static ViewModelLocator()
        {
            ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

            if (ViewModelBase.IsInDesignModeStatic)
            {
                SimpleIoc.Default.Register<IDataService, Design.DesignDataService>();
            }
            else
            {
                SimpleIoc.Default.Register<IDataService, DataService>();
            }

            SimpleIoc.Default.Register<MainViewModel>();
        }

        /// <summary>
        /// Gets the Main property.
        /// </summary>
        public MainViewModel Main
        {
            get
            {
                return ServiceLocator.Current.GetInstance<MainViewModel>();
            }
        }

        /// <summary>
        /// Cleans up all the resources.
        /// </summary>
        public static void Cleanup()
        {
        }
    }
ServiceLocator SimpleIoc 这两个东西比较陌生,看ServiceLocator的注释

This class provides the ambient container for this application. If your framework
defines such an ambient container, use ServiceLocator.Current to get it.

  该类为应用程序提供了一个容器,如果你的框架定义了这么一个容器,那么你可以用ServiceLocator.Current来获取。

  既然是个容器,那么是干嘛的呢?继续看代码,ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);为这个容器置一个委托SimpleIoc.Default,可能看到IOC,马上就想到了控制反转,依赖注入。对~SimpleIoc就是MVVMLight实现的一个IOC容器,再看SimpleIoc.Default.Register方法,你就明白原来是往容器里塞东西(接口实现,类)。

有放就有取

public MainViewModel Main
        {
            get
            {
                return ServiceLocator.Current.GetInstance<MainViewModel>();
            }
        }

这也是页面绑定的属性

到现在我们只看到了个ViewModel的属性,嗯,看看ViewModel是怎样的

  public class MainViewModel : ViewModelBase
    {
        private readonly IDataService _dataService;

        /// <summary>
        /// The <see cref="WelcomeTitle" /> property's name.
        /// </summary>
        public const string WelcomeTitlePropertyName = "WelcomeTitle";

        private string _welcomeTitle = string.Empty;

        /// <summary>
        /// Gets the WelcomeTitle property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public string WelcomeTitle
        {
            get
            {
                return _welcomeTitle;
            }

            set
            {
                if (_welcomeTitle == value)
                {
                    return;
                }

                _welcomeTitle = value;
                RaisePropertyChanged(WelcomeTitlePropertyName);
            }
        }

        /// <summary>
        /// Initializes a new instance of the MainViewModel class.
        /// </summary>
        public MainViewModel(IDataService dataService)
        {
            _dataService = dataService;
            _dataService.GetData(
                (item, error) =>
                {
                    if (error != null)
                    {
                        // Report error here
                        return;
                    }

                    WelcomeTitle = item.Title;
                });
        }

        ////public override void Cleanup()
        ////{
        ////    // Clean up if needed

        ////    base.Cleanup();
        ////}
    }

  它继承了ViewModelBase,其实它还是实现了 INotifyPropertyChanged, System.ComponentModel.INotifyPropertyChanging这些个东西

是不是没有发现Model,呵呵,WelcomeTitle 不就是Model吗?

  今天到此为止,源码下载  如果对您有所帮助的话就顶个吧。

posted @ 2013-09-17 14:24  一文钱  阅读(3247)  评论(6编辑  收藏  举报