1.程序結構如圖所示:express
2.Model實現後端
在Model文件夾下新建業務類StudentModel,代碼以下:架構
public class StudentModel : INotifyPropertyChanged
{
private int studentId;框架
public int StudentId
{
get { return studentId; }
set
{
studentId = value;
NotifyPropertyChanged("StudentId");
}
}mvvm
private string studentName;ui
public string StudentName
{
get { return studentName; }
set { studentName = value; }
}this
private int studentAge;spa
public int StudentAge
{
get { return studentAge; }
set { studentAge = value; }
}
private string studentEmail;.net
public string StudentEmail
{
get { return studentEmail; }
set { studentEmail = value; }
}
private string studentSex;3d
public string StudentSex
{
get { return studentSex; }
set { studentSex = value; }
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propertyName)
{
if (propertyName != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
StudentModel類實現了接口INotifyPropertyChanged。當類實現該接口後,即可以執行綁定的客戶端發出某一屬性值已改變的通知。
3ViewModel實現
代碼以下:
public class StudentViewModel
{
public DelegateCommand ShowCommand { get; set; }
public StudentModel Student { get; set; }
public StudentViewModel()
{
Student = new StudentModel();
ShowCommand = new DelegateCommand();
ShowCommand.ExecuteCommand = new Action<object>(ShowStudentData);
}
private void ShowStudentData(object obj)
{
Student.StudentId = 1;
Student.StudentName = "tiana";
Student.StudentAge = 20;
Student.StudentEmail = "456456646@qq.com";
Student.StudentSex = "男";
}
}
public class DelegateCommand : ICommand
{
public Action<object> ExecuteCommand = null;
public Func<object, bool> CanExecuteCommand = null;
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
if (CanExecuteCommand != null)
{
return this.CanExecuteCommand(parameter);
}
else
{
return true;
}
}
public void Execute(object parameter)
{
if (this.ExecuteCommand != null)
{
this.ExecuteCommand(parameter);
}
}
public void RaiseCanExecuteChange()
{
if (CanExecuteChanged != null)
{
CanExecuteChanged(this, EventArgs.Empty);
}
}
}
代碼中,除了定義StudentViewModel類外,還定義了DelegateCommand類,該類實現了ICommand接口。
ICommand接口中的Execute()方法用於命令的執行,CanExecute()方法用於只是當前命令在目標元素上是否可用,當這種可用性發生改變時便會觸發接口中的CanExecuteChanged事件。
咱們能夠將實現了ICommand接口命令DelegateCommand賦值給Button(命令源)的Command屬性(只有實現了ICommandSource接口的元素才擁有該屬性),這樣Button便與命令進行了綁定。
MainWindow界面的xaml代碼以下:
<Window x:Class="WPFMVVMExample.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:WPFMVVMExample"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Label Content="學號" Height="28" HorizontalAlignment="Left" Margin="54,23,0,0" Name="labelStudentId" VerticalAlignment="Top"></Label>
<TextBox Text="{Binding Student.StudentId}" IsReadOnly="True" Height="23" HorizontalAlignment="Right" Margin="0,27,289,0" Name="textBoxStudentId" VerticalAlignment="Top" Width="120"></TextBox>
<Button Command="{Binding ShowCommand}" Content="顯示" Height="23" HorizontalAlignment="Left" Margin="345,27,0,0" Name="buttonShow" VerticalAlignment="Top" Width="75"></Button>
</Grid>
</Window>
MainWindow後端代碼以下:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new StudentViewModel();
}
}
}
5運行程序
運行程序,點擊「」顯示「按鈕」,即將數據綁定至界面顯示
6.說明
wpf中使用mvvm能夠下降UI顯示與後端邏輯代碼的耦合度,即使換界面時,只須要修改不多的邏輯代碼就能夠實現,甚至不用修改。
在wpf中使用數據綁定機制,當數據變化後,數據會通知界面變動的發生,而不須要經過訪問界面元素來修改值,這樣後端邏輯代碼中也就沒必要操做或者不多操做界面的元素了。
使用MVVM,能夠很好的配合WPF的數據綁定機制來實現ui與邏輯代碼的分離,mvvm中的view表示界面,負責頁面顯示,viewmodel負責邏輯處理,包括準備綁定的數據和命令,viewmodel經過view的datacontext屬性綁定至view,model爲業務模型,共viewmodel使用。
7.架構
若是你讀到這裏,你會發現,若是你之後要使用這種方式,以上的代碼大多都是在重複:實現INPC(INotifyPropertyChanged)或建立Command這其實就是大部分MVVM 的樣板,因此咱們能夠將實現INPC放到一個基類中,咱們把它叫作「ObservableObject」。對於RelayCommand類,咱們能夠將其移動到咱們的.net類庫中。這就是全部的mvvm框架開始所作的(如Prism,Caliburn)。