MVVM架构: Model + View + ViewModel
Model层是数据类的提供者;View是表示层;ViewModel是逻辑层。
该实例非常简单,只是把数据体加载到页面DataGrid上,没有ICommand相关的命令方法。
首先构筑Model层,这里新建User类及User类的集合UserModel类:
由于在View界面上需要Binding到User的属性,所以这里需要实现INotifyPropertyChanged接口,来提供通知功能。
如果不使用InotifyPropertyChanged声明,也可以在xaml页面上进行绑定,只是当后台数据改变时,不能通知xaml页面数据发生改变。而且当xaml页面数据发生改变的时候,也不能通知后台数据发生改变。
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.ComponentModel;
namespace MVVMDemo1
{
public class User:INotifyPropertyChanged
{
public User()
{
// Insert code required on object creation below this point.
}
//定义属性,并且使用NotifyPropertyChanged方法进行绑定通知
//如果不适用InotifyPropertyChanged声明,也可以在xaml页面上进行绑定,
//只是当后台数据改变时,不能通知xaml页面数据发生改变。
//而且当xaml页面数据发生改变的时候,也不能通知后台数据发生改变。
private string _Name;
public string Name
{
get { return _Name; }
set
{
_Name = value;
NotifyPropertyChanged("Name");
}
}
private bool _Active;
public bool Active
{
get { return _Active; }
set
{
_Active = value;
NotifyPropertyChanged("Active");
}
}
private string _Birthday;
public string Birthday
{
get { return _Birthday; }
set
{
_Birthday = value;
NotifyPropertyChanged("Birthday");
}
}
//实现INotifyPropertyChanged接口的方法
private void NotifyPropertyChanged(string info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
UserModel类:该类是User类的集合类,这里使用了ObservableCollection<T>泛型类,该类可以自动提供INotifyPropertyChanged方法,不要在属性里编写该方法,也能自动提供通知。
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
namespace MVVMDemo1.BusinessObject
{
public class UserModel
{
public UserModel()
{ }
//ObservableCollection<T> 类
//表示一个动态数据集合,在添加项、移除项或刷新整个列表时,此集合将提供通知。
//ObservableCollection<T> 类,它是实现 INotifyCollectionChanged 接口的数据集合的内置实现。
public static ObservableCollection<User> GetUserList()
{
ObservableCollection<User> _Users = new ObservableCollection<User>();
_Users.Add(new User() { Name = "Bill Moore", Birthday = "06/22/1978", Active = true });
_Users.Add(new User() { Name = "Victor Gad", Birthday = "10/22/1999", Active = true });
_Users.Add(new User() { Name = "Paul Gebo", Birthday = "08/15/1935", Active = false });
_Users.Add(new User() { Name = "Thomas Train", Birthday = "05/19/1967", Active = true });
return _Users;
}
}
}
接下来构筑ViewModel层:该层是为了把View层上的数据进行Binding使用,如果xaml页面上需要使用n个binding属性,那么ViewModel层也需要声明N个相对应的属性来提供Binding使用。
using System;
using System.ComponentModel;
using System.Collections.ObjectModel;
using MVVMDemo1.BusinessObject;
namespace MVVMDemo1
{
//ViewModel一定要实现INotifyPropertyChanged接口
public class MainViewModel : INotifyPropertyChanged
{
public MainViewModel()
{
Users = UserModel.GetUserList();
}
private ObservableCollection<User> _Users = new ObservableCollection<User>();
public ObservableCollection<User> Users
{
get { return _Users; }
set
{
//由于ObservableCollection<T> 类,它是实现 INotifyCollectionChanged 接口的数据集合的内置实现。
//所以这里就不用再写: NotifyPropertyChanged("Users");
_Users = value;
}
}
//INotifyPropertyChanged.PropertyChanged事件是在更改属性值的时候发生。
//PropertyChanged事件可以通过将null或者String.Empty用作PropertyChangedEventArgs中的属性名,
//指示该对象的所有属性都已变更。
private void INotifyPropertyChanged(string p)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(p));
}
}
//实现 INotifyPropertyChanged 接口事件
public event PropertyChangedEventHandler PropertyChanged;
}
}
最后是构筑View层,这里的View层非常简单,只是一个DataGrid来加载User数据而已,注意这里的Binding,以及需要制定DataContext为哪个ViewModel,这样才能通过DataContext把当前xaml文件里的Binding绑定到哪个ViewModel上的属性。
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MVVMDemo1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:ec="http://schemas.microsoft.com/expression/2010/controls" xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" mc:Ignorable="d"
x:Class="MVVMDemo1.MainPage"
Width="640" Height="480">
<StackPanel x:Name="LayoutRoot" Background="White">
<!--这里把ViewModel数据绑定到DataGrid上,ItemsSource后的Binding的意思是指绑定到ViewModel上的Users属性,
而且这个属性必须是用INotifyPropertyChanged声明过的才可以.
这里还需要主要必须要有DataContext数据上下文才可以完成绑定,可以再后置代码中声明,也可以再xaml文件里声明-->
<sdk:DataGrid Margin="63,33,48,38" ItemsSource="{Binding Users}" AutoGenerateColumns="False">
<sdk:DataGrid.Columns>
<!--这里的Bindding不用写成Users.Name,因为在ItemsSource中已经指定了Source为Users,所以可直接写属性Name-->
<sdk:DataGridTextColumn Header="姓名" Binding="{Binding Name}"/>
<sdk:DataGridCheckBoxColumn Header="激活与否" Binding="{Binding Active}"/>
<sdk:DataGridTextColumn Header="生日" Binding="{Binding Birthday}"/>
</sdk:DataGrid.Columns>
</sdk:DataGrid>
</StackPanel>
</UserControl>
后台文件制定DataContext:
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace MVVMDemo1
{
public partial class MainPage : UserControl
{
public MainPage()
{
// Required to initialize variables
InitializeComponent();
//在这里指定DataContext数据源为ViewModel
this.DataContext = new MainViewModel();
}
}
}