MvvmLight框架使用入門(二)


  上一篇我們簡單對MvvmLight做了介紹。羅列了三個DLL中,各個命名空間下主要類的定義及大致作用。因為只是范范的概論,對於從未接觸過MvvmLight的萌新來說,根本就是在晃點他們。不過萬事開頭難么,本篇則會以Hello World般的簡單例子,來給萌新們當頭一擊,教會他們使用MvvmLight最最基礎的部分。

  首先還是動手練習,打開免費又強大的Visual Studio 2015 Community,創建一個WPF Application。不創建Win10Universal App是因為MvvmLight V5.2還不能給Universal App自動添加ViewModel等代碼(我們下次自己加)。不使用8.1 Runtime App是因為我沒在自己電腦上裝8.1SDK ^o^。

  新建的WPF Application是一個簡單至極的空項目,僅有App.xamlMainWindow.xaml兩個文件。XAML文件空空如也。

  然后我們通過NuGet添加MvvmLight的類庫,完成之后多出ViewModel文件夾,包含以下兩個文件:

  MainViewModel.cs

  ViewModelLocator.cs

  另外App.xaml里將ViewModelLocator作為資源添加全局的Application.Resources里:

      <Application.Resources>
        <ResourceDictionary>
          <vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" xmlns:vm="clr-namespace:HelloMvvmLight.ViewModel" />
        </ResourceDictionary>
    </Application.Resources>

  非常遺憾沒有像Windows Phone工程那樣貼心的在MainWindow里添加對MainViewModelDataContext綁定,心情很糟糕的我們只有自己來了,順便給MainViewModel里加上HelloWord的字樣唄,完成后運行如下圖:

  下面我們來大致講解MvvmLight在程序中起到的作用。

  MainWindow對應的ViewModelMainViewModel,通常我們是在MainWindowXAMLcs文件里new一個ViewModel的實例,賦值給DataContext。但在MvvmLight中,創建實例的工作,交給了ViewModelLocator這個類。

  在類ViewModelLocator里,我們注冊了MainViewModel,並通過屬性Main來獲取實例。

    public class ViewModelLocator
    {
        /// <summary>
        /// Initializes a new instance of the ViewModelLocator class.
        /// </summary>
        public ViewModelLocator()
        {
            ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
            SimpleIoc.Default.Register<MainViewModel>();
        }

        public MainViewModel Main
        {
            get
            {
                return ServiceLocator.Current.GetInstance<MainViewModel>();
            }
        }
        
        public static void Cleanup()
        {
            // TODO Clear the ViewModels
        }
    }

  之前提到安裝MvvmLight庫時App.xaml添加了ViewModelLocator實例的資源,在XAML中以StaticResource key的形式獲取,BindingMainWindowDataContext。

    <Window.DataContext>
            <Binding Path="Main" Source="{StaticResource Locator}"></Binding>
    </Window.DataContext>

  使用ViewModelLocator有啥好處呢?

  首先ViewViewModel之間不再直接引用,而是通過ViewModelLocator關聯。

  其次儲存在ViewModelLocator里的ViewModel類似於單例的存在,可以在全局引用綁定。

  同時避免了某些情況下頻繁創建ViewModel,卻未做好資源釋放造成的內存泄漏。(這里並不是說所有的ViewModel都必須放到ViewModelLocator

  下面我們來看下Command是如何綁定的,通知PropertyChanged以及ViewModelBase類 。

  我們添加一個Button,然后通過Command來把文字修改為Hello MvvmLight

  ViewModel的代碼:

    public class MainViewModel : ViewModelBase
    {
        private string title;

        public string Title
        {
            get { return title; }
            set { Set(ref title , value); }
        }

        public ICommand ChangeTitleCommand { get; set; }

        /// <summary>
        /// Initializes a new instance of the MainViewModel class.
        /// </summary>
        public MainViewModel()
        {
            Title = "Hello World";
            ChangeTitleCommand = new RelayCommand(ChangeTitle);
        }

        private void ChangeTitle()
        {
            Title = "Hello MvvmLight";
        }
    }

  MainWindow的XAML:

<Window x:Class="HelloMvvmLight.MainWindow"
        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:local="clr-namespace:HelloMvvmLight"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <Binding Path="Main" Source="{StaticResource Locator}"></Binding>
    </Window.DataContext>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>
        <TextBlock Text="{Binding Title}"></TextBlock>
        <Button Grid.Row="1" Command="{Binding ChangeTitleCommand}"></Button>
    </Grid>
</Window>

  MvvmLight很貼心的為我們實現了RelayCommand類,該類繼承自ICommand接口。直接在XAML里綁定就可以了。當然如果是沒有提供Command屬性的控件,就需要用到Blend來添加behavior了(可以期待后續篇章介紹)。

  MvvmLightViewModelBase很有意思,繼承了INotifyPropertyChanged接口,並提供了一個Set方法來給屬性賦值,簡單理解就是不用自己在ViewModel實現INotifyPropertyChanged,然后在屬性賦值時通知了。當然MvvmLight也提供了手動通知的方法:

        protected virtual void RaisePropertyChanged([CallerMemberName] string propertyName = null);
           
        protected virtual void RaisePropertyChanged<T>(Expression<Func<T>> propertyExpression);

  至此一個最簡單的使用MvvmLight框架的程序已經完成了。因為是入門寫的比較簡單,請各位大牛輕踩。

代碼在這里


免責聲明!

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



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