【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嗎?

  今天到此為止,源碼下載  如果對您有所幫助的話就頂個吧。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM