Windows Phone 7天初學(6):熟悉MVVM模式

          MVVM模式構架分爲視圖層V、視圖模型層VM、模型層M,View主要用於界面呈現,ViewModel用於邏輯實現,Model用於數據的構造,而這三者能夠進行通信,對於簡單的應用大規模運用MVVM模式開始可能會降低開發效率,但Silverlight提供了強大的數據綁定機制,將View和ViewModel有效的聯繫起來,會大大提高開發效率,特別較爲複雜的應用,MVVM模式並有助於應用程序的測試、維護和升級,使得設計人員專注於界面設計,開發人員專注於代碼,他們並能很好的合作。
       Model 是應用程序的核心,代表着最大、最重要的業務資產,因爲它記錄了所有複雜的業務實體、它們之間的關係以及它們的功能。Model 之上是 ViewModel。ViewModel 的兩個主要目標分別是:使 Model 能夠輕鬆被 WPF/XAML View 使用;將 Model 從 View 分離並對 Model 進行封裝。這些目標當然非常好,但是由於一些現實的原因,有時並不能達到這些目標。
        您構建的 ViewModel 知道用戶在高層上將如何與應用程序交互。但是,ViewModel 對 View 一無所知,這是 MVVM 設計模式的重要部分。這使得交互設計師和圖形設計師能夠在 ViewModel 的基礎上創建優美、有效的 UI,同時與開發人員密切配合,設計適當的 ViewModel 來支持其工作。此外,View 與 ViewModel 的分離還使得 ViewModel 更有利於單元測試和重用。
        MVVM 模式中存在三個核心組件:模型、視圖和視圖模型。除了瞭解這三個組件的作用,還要了解這些組件相互之間如何交互,這也很重要。從最高層面上來說,視圖“瞭解”視圖模型,視圖模型“瞭解”模型,但模型不瞭解視圖模型,視圖模型不瞭解視圖,下圖  演示了這三個組件之間的關係
 
 
 
是在 MVVM 模式中清楚地劃分職責的一些好處:
• 在開發過程中,開發人員和設計人員可以更好地獨立和並行處理各自的組件。設計人員可將精力集中在視圖上,如果他們使用的是 Expression Blend,則可以輕鬆生成要處理的示例數據,而開發人員可處理視圖模型和模型組件。
• 開發人員可爲視圖模型和模型創建單元測試而不使用視圖。視圖模型的單元測試可準確地執行視圖使用的相同功能。
• 由於視圖完全在 XAML 中實現,因此可以輕鬆地重新設計應用程序 UI 而不必改動代碼。新版本的視圖應可以與現有視圖模型一起使用。
• 如果現有的模型實現封裝了現有業務邏輯,則更改起來可能存在難度或風險。在這種情況下,視圖模型將充當模型類的適配器,您可以通過它避免對模型代碼做出重大更改。
一Model模型層
Model模型層是一個面向對象的實體類。如:
首先在Student.cs中簡單聲明瞭一個類
        public class Student
       {
           public string name { get; set;}
            public int age  { get; set; }
           public string class { get; set;}
 }
     類型定義好後,我們在Students.cs中得到一個Student的集合
        public class Students
       {
        public List<Student> listStudent;
        public List<Student> GetStudentS()
        {
            listStudent = new List<Student>()
            {
                new Student {name = "Tom",  age = 21,Class=”一年級二班” },
                new Student {name = "Jack", age = 22 ,Class=”一年級二班”},
                new Student {name = "Rose", age = 23 ,Class=”一年級二班”},
            };
            return listStudent;
        }
     }
二、ViewModel視圖模型層
ViewModel是視圖模型層 這一層是對View視圖層展現、數據的讀取以及各種事件的處理。如:
public class ViewModel 
       {
         public List<Students> vStudents { get; set; }
         public ViewModel()
         {
             vStudents = new Students ().GetStudentS ();
         }     
       }
Command命令一般都需要定義成獨立的類來實現,然後再ViewModel上實例化
Command命令類的實現的方法可以繼承ICommand 使用第三方組件的Command命令的類
繼承ICommand 的語法如下
    public class MyCommand<T> : ICommand
    {
        Action<T> Excuted;
        Func<bool> canExcute;
        public ShowMessageCommand(Action<T> excuted)
        {
            this.Excuted = excuted;
        }
        public bool CanExecute(object parameter)
        {
            return true;
        }
        public event EventHandler CanExecuteChanged;
        public void Execute(object parameter)
        {
            //你的需要執行的代碼
           
        }
    }
三、View視圖層
      View視圖層是界面的設計,文件表現爲xaml文件。
先在應用程序中定義爲資源:
<Application.Resources>
        <vmmodel: ViewModel x:Key=" vStudents "></vmmodel: ViewModel>
       </ Application.Resources>
也可在具體頁中定義。
<UserControl.Resources>
        <vmmodel: ViewModel x:Key=" vStudents "></vmmodel: ViewModel>
<UserControl.Resources>
頁面引用:
        <Grid x:Name="LayoutRoot" Background="White" DataContext="{StaticResource vStudents }" >

實現綁定:
<DataTemplate>
                            <StackPanel>
                                <TextBlock HorizontalAlignment="Left" Name="textBlock1" Text="{Binding name}" VerticalAlignment="Top" />
                                <TextBlock HorizontalAlignment="Left" Name="textBlock2" Text="{Binding age}" VerticalAlignment="Top" />
<TextBlock HorizontalAlignment="Left" Name="textBlock2" Text="{Binding Class}" VerticalAlignment="Top" />
                            </StackPanel>
           </DataTemplate>

案例6:MVVM模式
   這是一個MVVM模式,在前面的講解的基礎上,實現更多的功能, MVVM模式重點是實現綁定,而其中的難點是命令綁定,下面舉例說明命令綁定的實現。該例實現一個矩形的放大縮小。
(1) 新建一個Windows Phone Project。創建Command、ViewModel二個文件夾,用於創建對應於的文件,此類功能簡單Model層不必創建、View層就直接用MainPage.xaml。
(2)在Model目錄下創建類ExecuteCommandAction.cs,以便在首頁實現綁定,主要代碼如下:
public class ExecuteCommandAction:TriggerAction<FrameworkElement>
    {
        public static readonly DependencyProperty CommandNameProperty =
             DependencyProperty.Register("CommandName", typeof(string), typeof(ExecuteCommandAction), null);
        public static readonly DependencyProperty CommandParameterProperty =
            DependencyProperty.Register("CommandParameter", typeof(object), typeof(ExecuteCommandAction), null);
        protected override void Invoke(object parameter)
        {
            if (AssociatedObject == null)
                return;
            ICommand command = null;
            var dataContext = AssociatedObject.DataContext;//調用視圖的上下文Content
            foreach (var info in dataContext.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
            {
                if (IsCommandProperty(info) && String.Equals(info.Name, CommandName, StringComparison.Ordinal))//找到命爲"AddRadius"的ICommand:AddRadius
                {
                    command = (ICommand)info.GetValue(dataContext, null);
                    break;
                }
            }
            if ((command != null) && command.CanExecute(CommandParameter))
            {
                command.Execute(CommandParameter);//運行AddRadius,AddRadius命令內容就是增加半徑
            }
        }
        private static bool  IsCommandProperty(PropertyInfo property)
        {
            return typeof(ICommand).IsAssignableFrom(property.PropertyType);
        }
(3)在ViewModel目錄下創建視圖模型類:
public class RadiusViewModel : INotifyPropertyChanged
    {
        private Double radius;
        public RadiusViewModel()
        {
            Radius = 0;
          AddRadius = new ActionCommand(p => Radius += 50);
            ShuRadius = new ActionCommand(p => Radius -= 10);
        }
        public event PropertyChangedEventHandler PropertyChanged;
       
        public ICommand AddRadius
        {
            get;
            private set;
        }
        public ICommand ShuRadius
        {
            get;
            private set;
        }       
        public Double Radius
        {
            get
            {
                return radius;
            }
            set
            {
                radius = value;
                OnPropertyChanged("Radius");
            }
        }
(5)在首頁MainPage創建RadiusViewModel實體,聲明爲資源,在頁面長方形的寬、高綁定其中的屬性Radius:
<!--設置整個頁面DataContext爲視圖模型類RadiusViewModel-->
    <phone:PhoneApplicationPage.DataContext>
        <my:RadiusViewModel/>
    </phone:PhoneApplicationPage.DataContext>
 
<Rectangle  Fill="Blue" 
                     Height="{Binding Radius}" Width="{Binding Radius}" 
                     HorizontalAlignment="Left" Margin="71,78,0,0" Name="ellipse1" Stroke="Black" StrokeThickness="1" VerticalAlignment="Top" />
   
(6) 綁定命令,實現放大、縮小的功能
<Button Content="放大" Height="72" HorizontalAlignment="Left" Margin="71,468,0,0" Name="button2" VerticalAlignment="Top" Width="160" >
                <Custom:Interaction.Triggers>
                    <Custom:EventTrigger EventName="Click">
                        <my_Interactivity:ExecuteCommandAction CommandName="AddRadius"/>
                    </Custom:EventTrigger>
                </Custom:Interaction.Triggers>
            </Button>
            <Button Content="縮小" Height="72" HorizontalAlignment="Left" Margin="253,468,0,0" Name="button3" VerticalAlignment="Top" Width="160" >
                <Custom:Interaction.Triggers>
                    <Custom:EventTrigger EventName="Click">
                        <my_Interactivity:ExecuteCommandAction CommandName="ShuRadius"/>
                    </Custom:EventTrigger>
                </Custom:Interaction.Triggers>
            </Button>
 
運行,可看到如下效果:
 

  這是一個簡單案例,主要實現了一個命令綁定,實際應用中可能更復雜,按照MVVM模式的思想編寫的程序應該拋棄Xaml文件的code behind(即xaml.cs)文件,這樣才能讓開發和設計各盡其能,MVVM模式的View與ViewModel有三大通訊方式:Binding Data(實現數據的傳遞)、Command(實現操作的調用)和Attached Behavior(實現控件加載過程中的操作)。
         在www.CodePlex.com上有許多不錯的第三方MVVM框架可供我們借鑑和使用,較常用的有下面兩個:
MVVM Light Toolkit是幫助人們在Silverlight和WPF中使用MVVM設計模式的一套組件。它是一個輕量級的、務實的框架,只包含所需的必要組成部分。
下載地址: http://mvvmlight.codeplex.com/
Simple MVVM Toolkit使開發應用MVVM設計模式Widnows Phone的應用程序變得更容易,爲基於 MVVM設計模式的應用程序提供一個簡單的框架和工具集。Simple MVVM Toolkit的特點是簡單,但它包含執行 MVVM 設計模式的應用程序所需的一切。
下載地址: http://simplemvvmtoolkit.codeplex.com/
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章