管窺MVVMLight Command參數綁定和事件傳遞

前言框架

因爲在實際項目中,業務功能的增長致使軟件開發規模在逐漸變大,因此我準備找個Silverlight框架來組織當前項目中的文件,以期可以讓後續的業務功能增添和維護更加容易一些。無心中,我在這篇文章中看到了當前Silverlight下全部的框架的評測:Discover and compare existing MVVM frameworks !,當我看到MvvmLight toolkit在各方面都比較完備的時候,因而決定選擇這個框架:less

image

Codeplex網站上,下載了MVVM Light Toolkit V4 RTM這個版本,由於我用的是vs2010,因此我下載了支持當前機器IDE的版本。mvvm

新建項目,選擇MvvmLight(SL4),以後咱們就能夠看到項目結構了:網站

image

其中:this

Design文件夾中的文件主要提供設計時運行支持url

Model文件夾則放置了富實體模型設計

Skins文件夾則放置了樣式文件定義3d

ViewModel文件夾則放置了ViewModel對象,其實MainViewModel和MainPage是一對一的(ViewMoel-View)關係.兩者的映射經過ViewModelLocator進行。code

MainPage.xaml就是咱們的視圖頁面orm

下面咱們就以例子來演示MvvmLight Toolkit中是如何實現MVVM模式,如何綁定命令,如何進行事件消息傳遞的。

首先,在這個框架中,MVVM模式的入口點爲ViewModelLocator類,在這個類中,能夠定義多個ViewModel屬性,而且每一個屬性均可以經過ServiceLocator.Current.GetInstance方法進行映射,以便於暴露給前臺綁定。同時,在新增一個ViewModel類的時候,必定要在其提供的SimpleIoc對象容器中進行註冊,以便於可以經過IOC的方式獲取其實例。

作完映射後,就是咱們的ViewModel對象了。它須要繼承自ViewModelBase類,這個類封裝了ICommand,INotifypropertyChanged等接口,使用起來很方便。好比能夠用RaisePropertyChanged直接來拋出變動通知。

以後就是View了,在View中,咱們須要先對DataContext進行綁定:

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

而後就能夠爲所欲爲的操做了。

 

而後,咱們來說解下綁定命令。

因爲命令綁定是應用程序中必不可少的環節,因此這裏我以 綁定無參事件,綁定一個參數事件,綁定多個參數事件來講明。

綁定無參事件:

  #region Command without parameters
        private RelayCommand showText;
        public RelayCommand ShowText
        {
            get
            {
                if (showText == null)
                    showText = new RelayCommand(ShowTextFunc);
                return showText;
            }
        }
        public RelayCommand PassEvent { get; set; }
        
        private void ShowTextFunc()
        {
            MessageBox.Show("I am RealyCommand!");
        }
        #endregion

上面代碼就是綁定無參事件,在View上能夠經過以下方式綁定:

 <Button Content="綁定無參事件" 
 		 Command="{Binding ShowText}" 
		 Height="23" 
		 HorizontalAlignment="Left" 
		 Margin="32,62,0,0" 
		 Name="button1" 
		 VerticalAlignment="Top" 
		 Width="141" />

 

綁定一個參數事件:

 #region Command with a parameter 
        private RelayCommand<int> showValue;
        public RelayCommand<int> ShowValue
        {
            get
            {
                if (showValue == null)
                    showValue = new RelayCommand<int>(x=>ShowValueFunc(x));
                return showValue;
            }
        }

        private int ShowValueFunc(int a)
        {
            int c = a + 10;
            MessageBox.Show(c.ToString());
            return c;
        }
        #endregion

上面的代碼部分就是綁定一個參數的事件定義,咱們來驅動view層:

<Button Content="綁定一個參數事件" 
        Command="{Binding ShowValue}" 
		CommandParameter="{Binding ElementName=textBox1,Path=Text,Converter={StaticResource IntConverter}}" 
		Height="23" 
		HorizontalAlignment="Left" 
		Margin="32,103,0,0" 
		Name="button2" 
		VerticalAlignment="Top" 
		Width="141" />

須要說明的是,上面代碼示例中,CommandParameter的值來自於textBox1的Text屬性中。這個值加上10之後返回。

若是遇到用戶輸入不是數字的狀況,則經過IntConverter方法將用戶輸入格式化,而後返回:

public class IntConverter:IValueConverter
    {

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            int result;
            if(Int32.TryParse(value.ToString(),out result))
            {
                return result;
            }
            return "0";
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

綁定多個參數事件:

因爲RelayCommand默認最多容許一個參數傳遞,因此這裏若是想傳遞多個數據對象,只可以去構建本身的DTO了。

在Model文件夾新建一個BookItem類:

public class BookItem
    {
        public string BName { get; set; }
        public string BAuthor { get; set; }
    }

而後在ViewModel中進行以下控制:

 #region Command with multiple parameters
        private RelayCommand<BookItem> showBooks;
        public RelayCommand<BookItem> ShowBooks
        {
            get
            {
                if (showBooks == null)
                    showBooks = new RelayCommand<BookItem>(x=>ShowBooksFunc(x));
                return showBooks;
            }
        }

        private void ShowBooksFunc(BookItem bookItem)
        {
            MessageBox.Show(bookItem.BName+"|"+bookItem.BAuthor);
        }
        #endregion

驅動View層:

 <Button Command="{Binding ShowBooks}"  
         Content="綁定多個參數事件" 
		 Height="23" 
		 HorizontalAlignment="Left" 
		 Margin="32,141,0,0" 
		 Name="button3" 
		 VerticalAlignment="Top" 
		 Width="141" >
            <Button.CommandParameter>
                <model:BookItem BName="testName" BAuthor="TestAuthor" ></model:BookItem>
            </Button.CommandParameter>
 </Button>

運行起來得時候,咱們發現BookItem參數已經被自動賦值了。

ViewModel之間事件傳遞

最後須要講解的是如何在ViewModel之間進行事件傳遞。因爲在MVVMLight Toolkit中已經集成了Messenger對象,因此咱們能夠利用其很方便的進行事件傳遞,下面新建一個ChildWindow1.xaml子窗體,而後在ViewModelLocator中添加以下代碼:

 public ChildViewModel Child
        {
            get
            {
                return ServiceLocator.Current.GetInstance<ChildViewModel>();
            }
        }
SimpleIoc.Default.Register<ChildViewModel>();

而後在ViewModel文件夾中新建一個ChildViewModel類,在其中添加以下代碼:

 public class ChildViewModel:ViewModelBase
    {
        public ChildViewModel()
        {
            Messenger.Default.Register<BookItem>(this, message =>
            {
                MyText = message.BName + "|" + message.BAuthor;
            });
        }
        public string MyText { get; set; }
    }

因爲咱們傳遞的對象是從 MainViewModel到ChildViewModel,因此咱們在MainViewModel中添加以下發送代碼:

 #region Messenger communication cross page
        private RelayCommand showChildWindow;
        public RelayCommand ShowChildWindow
        {
            get
            {
                if (showChildWindow == null)
                    showChildWindow = new RelayCommand(ShowChildWindowFunc);
                return showChildWindow;
            }
        }

        private void ShowChildWindowFunc()
        {
            ChildWindow1 child = new ChildWindow1();
            child.Show();
            var bookItem = new BookItem() { BAuthor="TestAuthor",BName="TestName" };
            Messenger.Default.Send<BookItem>(bookItem);
        }
        #endregion

這樣當運行起來的時候,咱們就能看到效果了:

image

好了,暫時就到這裏,後面咱們再深刻挖掘。

百度網盤下載

騰訊微盤下載

相關文章
相關標籤/搜索