MVVM模式主要是为了实现视图和逻辑的分离,下面介绍一下完整实例:
① 首先是在数据部分,即Model层。在此定义AuthorVO类,其中包括所用的基本属性。
public class AuthorVO : INotifyPropertyChanged, IDataErrorInfo
{
#region 私有字段
private DateTime? _StartDate;
private DateTime? _EndDate;
private string _Name;
#endregion
public AuthorVO ()
{
this.CanShow = false;
this.CanEdit = false;
this.CanDelete = false;
}
/// <summary>
/// 复制一个等同于自己的实体
/// </summary>
public AuthorVO Copy()
{
return (AuthorVO )this.MemberwiseClone();
}
/// <summary>
/// 取得或设置ID
/// </summary>
public string ID
{
get;
set;
}
/// <summary>
/// 取得或设置编码
/// </summary>
public string Code
{
get;
set;
}
/// <summary>
/// 取得或设置姓名
/// </summary>
[Required(ErrorMessage = "航段名称不能为空!")]
public string Name
{
get
{
return _Name;
}
set
{
if (_Name != value)
{
_Name = string.IsNullOrEmpty(value) ? value : value.Trim();
OnPropertyChanged("Name");
}
}
}
② 其中在View和ViewModel层之间是通过数据绑定联系在一起的。
View层的xaml文件代码:
<Base:RadWindowBase x:Class="*.Client.View.*.*.*"
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:Beh="clr-namespace:OceanSample.Client.View.Extension"
xmlns:Base="clr-namespace:OceanSample.Client.View"
WindowStartupLocation="CenterScreen" Header="信息管理"
Padding="10" ResizeMode="NoResize"
>
<Control.InputBindings>
<KeyBinding Gesture="Ctrl+S" Key="S" Command="{ Binding Path=SaveCommand}"/>
</Control.InputBindings>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="45"/>
<RowDefinition Height="110"/>
<RowDefinition Height="45"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="150"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="2" Grid.Row="2" Style="{ StaticResource TextBlockStretchStyle}">
<Run>次序:</Run>
</TextBlock>
<telerik:RadMaskedTextBox ToolTip="次序" IsReadOnly="True"
Style="{ StaticResource ResourceKey=RadMaskedTextBoxStretchStyle}"
Grid.Column="3" Grid.Row="2" TabIndex="5" x:Name="Order"
Value="{ Binding Path=*.Order,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
Margin="5,5,5,5" MaskType="None"
>
</telerik:RadMaskedTextBox>
<StackPanel Grid.Row="6" Grid.Column="0" Grid.ColumnSpan="6" HorizontalAlignment="Center" Orientation="Horizontal" >
<telerik:RadButton Content="保存" Width="60" Height="30" TabIndex="11" Margin="5"
HorizontalAlignment="Center" HorizontalContentAlignment="Center"
Command="{ Binding SaveCommand}"
/>
<telerik:RadButton Content="取消" Width="60" Height="30" HorizontalContentAlignment="Center" TabIndex="12"
HorizontalAlignment="Center" Margin="5" Command="{ Binding CloseCommand}"
/>
</StackPanel>
</Grid>
</Base:RadWindowBase>
在后台代码中:
/// <summary>
/// Interaction logic for Author.xaml
/// </summary>
public partial class Author : RadWindowBase
{
public Author()
{
InitializeComponent();
DataContext = new AuthorViewModel();
}
}
③ 在ViewModel层,实现数据和界面之间的逻辑,在类中,包括了属性和命令,都将与界面进行数据绑定,
其中Command只能与具有Comman属性的控件进行绑定,否则就要采用其他的方式,但是在这里使用的是按钮,
所以可以进行。实现命令时,自定义命令时要实现ICommand接口,在UI界面中,一般会继承RouteCommand或是
RouteUICommand,这都是有弊端的,所以大家一般采用,自定义一个RelayCommand,但是要注册多个命令时,
定义将会有所改动。
ViewModel的定义代码:
public class AuthorViewModel : ViewModelClassBase
{
#region 私有字段
private BaseCommand _AddCommand;
//判断数据是否加载忙碌状态
private bool _IsBusy;
//每一行显示的信息数目
private int _PageSize = 20;
//定义的状态信息
private OperationStatus _OperationStatus;
#endregion
#region 构造函数
/// <summary>
/// 构造函数
/// </summary>
public AuthorViewModel()
{
_OperationStatus = new OperationStatus();
//加载数据
DataLoad(null);
//订阅实体(获得编辑界面发布的事件)
EventAggregatorForSubscribe.GetEvent<AddOrEditEntityHanleEvent>().Subscribe(AddOrEditLeg,
ThreadOption.PublisherThread, false, CanAddOrEdit);
}
#endregion
#region 绑定属性
/// <summary>
/// 添加
/// </summary>
public ICommand AddCommand
{
get
{
if (_AddCommand == null)
_AddCommand = new BaseCommand(Add, CanAdd);
return _AddCommand;
}
}
/// </summary>
public int PageSize
{
get
{
if (_PageSize < 0)
_PageSize = 0;
return _PageSize;
}
set
{
if (_PageSize != value && value >= 0)
{
_PageSize = value;
OnPropertyChanged("PageSize");
}
}
}
/// <summary>
/// 是否在加载数据
/// </summary>
public bool IsBusy
{
get
{
return _IsBusy;
}
set
{
if (_IsBusy != value)
{
_IsBusy = value;
OnPropertyChanged("IsBusy");
}
}
}
#endregion
#region 方法事件
/// <summary>
/// 添加命令方法
/// </summary>
/// <param name="obj"></param>
public void Add(object obj)
{
EventAggregatorForPublish.ShowControl("添加信息", "Display.*.*",
new List<object> { "*.Client.ViewModel.Display.*.*", new AuthorVO() });
}
#endregion
#region 权限
/// <summary>
/// 添加权限
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public bool CanAdd(object obj)
{
return !IsBusy;
}
#endregion
至此,程序框架基本建立。