MVVM模式
一、MVVM模式概述
MVVM Pattern : Model\View\ViewModel
View:視圖、UI界面
ViewModel:ViewModel是對Model的封裝,通過一系列屬性暴露Model的狀態,提供給View進行顯示
Model:數據模型
使用MVVM模式可以將代碼邏輯和UI進行分離,因此開發團隊可以關注創建健壯的ViewModel類,而設計團隊可以關注設計界面友好的View。要融合兩個團隊輸出只需要在View的xaml上進行正確的綁定即可。
二、演示程序
下面通過一個Demo演示WPF中如何使用MVVM模式:使用WPF中的data template、commands、data binding、resource結合MVVM模式,創建一個簡單、可測試、健壯的框架。
演示程序結構圖如下:
1、演示程序 Demo界面如圖所示:
工作區用於顯示視圖
命令區分兩部分,上部分為顯示單視圖命令,下部分為顯示多視圖命令
單視圖:工作區始終只顯示一個視圖。
多視圖:工作區可以顯示多個視圖,以TabControl控件的TabItem進行展示。可以通過previousview命令顯示視圖集合中的上一個視圖,通過nextview顯示視圖集合中的下一個視圖。
Demo的MainWindow.xaml文件中,使用單視圖時,需要注釋多視圖;使用多視圖時,需要注釋單視圖。代碼如下:
<!--single view--> <ContentPresenter Content="{Binding Path=WorkspaceSingle}"/> <!--multi view--> <ContentPresenter Content="{Binding Path=WorkspaceMulti}" ContentTemplate="{StaticResource WorkspacesTemplate}"/>
三、數據模型(Model)、視圖(View)
為了使Demo更容易理解,程序中只使用了一個Model,Model中Name屬性用於顯示視圖名稱。
public class InfoModel { //視圖名稱 public string Name { get; set; } }
兩個簡單的視圖:FirstView、SecondView,視圖中控件顯示當前的視圖名稱,如視圖FirstView:
<StackPanel Background="Aqua"> <TextBlock Text="{Binding Path=Name}" FontSize="20"/> </StackPanel> <StackPanel Background="Chartreuse"> <TextBlock Text="{Binding Path=Name}" FontSize="20"/> </StackPanel>
在實際開發中,視圖中可以布局其它控件,並進行正確的綁定,界面都能正常的顯示。
顯示多視圖時,TabItem的Header能顯示視圖名稱,如圖所示:
視圖名稱DisplayName是基類ViewModelBase的屬性
/// <summary> /// 名稱 /// </summary> public virtual string DisplayName { get; protected set; }
子類在構造函數中給DisplayName賦值
public class FirstViewModel : WorkspaceViewModel { private const string DisplayViewName = "FirstView"; private readonly InfoModel _info; public FirstViewModel() { //視圖名稱 base.DisplayName = DisplayViewName; if (_info == null) { _info = new InfoModel(); } _info.Name = DisplayViewName; } public string Name { get { return _info.Name; } } }
在View中綁定視圖名稱
<DataTemplate x:Key="TabItemTemplate"> <DockPanel> <ContentPresenter Content="{Binding Path=DisplayName}" VerticalAlignment="Center"/> </DockPanel> </DataTemplate>
四、ViewModel類圖
大家一看代碼就知道,整個ViewModel使用的是什么設計模式
五、View對應ViewModel
Demo的一個主要特點是數據延遲加載,即在需要數據時創建ViewModel
程序在啟動時即為主界面加載數據MainWindowViewModel
public partial class App : Application { protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); MainWindow window = new MainWindow(); var viewModel = new MainWindowViewModel(); window.DataContext = viewModel; window.Show(); } }
程序啟動后,單擊按鈕時創建FirstViewModel或SecondViewModel
創建單視圖
/// <summary> /// 顯示視圖一 /// </summary> private void ShowFirstView() { if (_workspaceStory == null) { _workspaceStory = new ObservableCollection<WorkspaceViewModel>(); } var model = this._workspaceStory.FirstOrDefault(vm => vm is FirstViewModel) as FirstViewModel; if (model == null) { model = new FirstViewModel(); _workspaceStory.Add(model); } WorkspaceSingle = model; } /// <summary> /// 顯示視圖二命令 /// </summary> private void ShowSecondView() { if (_workspaceStory == null) { _workspaceStory = new ObservableCollection<WorkspaceViewModel>(); } var model = this._workspaceStory.FirstOrDefault(vm => vm is SecondViewModel) as SecondViewModel; if (model == null) { model = new SecondViewModel(); _workspaceStory.Add(model); } WorkspaceSingle = model; }
創建多視圖
/// <summary> /// 創建視圖一,並顯示 /// </summary> private void CreateFirstView() { var model = new FirstViewModel(); WorkspaceMulti.Add(model); ShowCurrentView(model); } /// <summary> /// 創建視圖二 /// </summary> private void CreateSecondView() { var model = new SecondViewModel(); WorkspaceMulti.Add(model); ShowCurrentView(model); }
創建后,WPF自動為匹配的View Model尋找View來渲染。
<DataTemplate DataType="{x:Type vm:FirstViewModel}"> <vw:FirstView/> </DataTemplate> <DataTemplate DataType="{x:Type vm:SecondViewModel}"> <vw:SecondView/> </DataTemplate>
六、總結
MVVM模式是設計和開發WPF程序一種簡單、有效的指導方針。它允許你創建數據、行為和展示強分離的程序,更容易控制軟件開發中的混亂因素。