mysql的mvvm_MVVM开发模式简单实例MVVM Demo

本文介绍了MVVM设计模式的基本概念,并提供了一个简单的WPF应用示例,包括Model、View和ViewModel的职责。Model负责保存数据和属性验证,View负责用户界面展示,ViewModel处理业务逻辑。文中通过ProductModel、ProductViewModel和View的交互展示了MVVM模式的实现,强调了属性更改通知和命令(RelayCommand)在数据绑定中的作用。
摘要由CSDN通过智能技术生成

本文主要是翻译Rachel Lim的一篇有关MVVM模式介绍的博文 A Simple MVVM Example

并具体给出了一个简单的Demo(原文是以WPF开发的,对于我自己添加或修改的一部分会用红色标注)

现在开始:

在我看来,如果你使用的是WPF或Sliverlight来开发程序就应该使用MVVM设计模式。它是你的代码清晰明了并易于维护。

可问题是网上有很多有关MVVM模式的资源都有自己强大的实现方式。这里我将介绍最基础的MVVM设计模式的实现方法。

MVVM(是Model-View-ViewModel的缩写)

Model: 保存数据的简单类对象,它只能包含属性和属性验证(应该就是验证属性值是否正确),而不负责存储数据、事件点击、复杂运算、业务规则和其他操作。

View: 呈现给用户的数据界面,很多情况下,他是以数据模板(DataTemplates)的方式告诉应用如何呈现类中内容的。

如果代码内容只跟View有关(比如社交焦点和执行动画),可以将代码写在View的后台。

ViewModel:用来处理逻辑。你的后台代码(数据访问、点击事件、复杂运算、业务规则验证等)都写在这里。这里面的代码View的反应。

比如,View中有一个ListBox对象、选中的对象、保存按钮。ViewModel中就要包含ObservableCollection集合、

Mode类型的SelectedObject和命令ICommand SaveCommand.

下面就通过一个简单的例子看看这三者之间是如何相互联系的。你会发现除了属性和方法名,任意一者是不需要访问另外两者的。

一旦接口被定义了,每一层可以完全独立于其他运行。

此例中,我使用的是Product Model,这个类中只含有属性和属性更改通知(INotifyPropertyChanged)

1.Model

public classProductModel : ObservableObject

{//字段

private int_productId;private string_productName;private decimal_unitPrice;//属性

public intProductId

{get { return_productId; }set{

SetProperty(ref this._productId, value);

}

}public stringProductName

{get { return_productName; }set{

SetProperty(ref this._productName, value);

}

}public decimalUnitPrice

{get { return_unitPrice; }set{

SetProperty(ref this._unitPrice, value);

}

}publicProductModel()  //这里的构造函数只是为了后面TextBlock能够以此方法绑定显示:Text="{Binding CurrentProduct.ProductId}"

{this.ProductName = "Lumia 930";this.ProductId = 123;this.UnitPrice = 2799;

}

}

ProductModel继承了ObservableObject类,而ObservableObject实现了INotifyPropertyChanged接口

(ObservableObject和原文不一样,只是简化了一下,具体可以查看 INotifyPropertyChanged接口的实现,介绍的很详细)

public classObservableObject: INotifyPropertyChanged

{public eventPropertyChangedEventHandler PropertyChanged;public bool SetProperty(ref T storage, T value, [CallerMemberName]string propertyName = null)

{if (object.Equals(storage, value)) return false;

storage=value;this.OnPropertyChanged(propertyName);return true;

}protected void OnPropertyChanged([CallerMemberName]string propertyName = null)

{var eventHandler = this.PropertyChanged;if (null !=eventHandler)

{

eventHandler(this, newPropertyChangedEventArgs(propertyName));

}

}

}

注意:属性更改通知(INotifyPropertyChanged):当Model中属性更改时,会通知View实时的更新View页面。

有人建议将这个放入ViewModel而不是Model中。虽然两种方式都是有效的,但是我发现放入ViewModel更加复杂,

还需要更多的代码。而放入Model中更简单些。[的确,很多例子都是有ViewModel来继承的...不知道为什么这里要Model继承。。有更加复杂么?]

2.ViewModel

由于在创建View之前需要ViewModel,接下来我们就来创建ViewModel。它要包括用户操作所有的交互。

现在这里包括4个属性:CurrentProduct当前产品, 产品获取命令GetProductCommand,保存命令SaveProductCommand.用来查找某个产品的ProductId

public classProductViewModel : ObservableObject

{private int_productId;privateProductModel _currentProduct;privateICommand _getProductCommand;privateICommand _saveProductCommand;public intProductId

{get { return_productId; }set{

SetProperty(ref this._productId, value);

}

}

public ProductViewModel()

{

CurrentProduct = new ProductModel();    }publicProductModel CurrentProduct

{get { return_currentProduct; }set{if (null ==_currentProduct)

_currentProduct= newProductModel();

_currentProduct=value;

}

}publicICommand SaveProductCommand

{get{if (_saveProductCommand == null)

{

_saveProductCommand= newRelayCommand(SaveProduct);  //实例化构造时和原文参数不一样

}return_saveProductCommand;

}

}publicICommand GetProductCommand

{get{if (_getProductCommand == null)

_getProductCommand= newRelayCommand(GetProduct, IsEnable);  //实例化构造时和原文参数不一样return_getProductCommand;

}

}public boolIsEnable()  //此控件是否可点击 {return true;

}public voidSaveProduct()  //执行命令 {await new MessageDialog("保存").ShowAsync();}

public void GetProduct(object parameter)  {

if (parameter.ToString() == string.Empty)  //多做了一个判断

return;

ProductId = int.Parse(parameter.ToString());

ProductModel product = new ProductModel();

product.ProductName = "Test Product";

product.ProductId = ProductId;

product.UnitPrice = 10.00M;

CurrentProduct = product;

}}

这里出现了一个新类RelayCommand,MVVM的正常使用必不可少。这个命令表示的是由其他类调用委托来实现此类中的代码

[在建立非空项目的时候Command文件夹会自动生成此类,但是本身只定义了不带参数的方法,需要进行扩展---注释部分]

public classRelayCommand : ICommand

{private readonlyAction _execute;private readonly Func_canExecute;private readonly Action_executeParam;  //新增了一个带参数有返回值的方法

public eventEventHandler CanExecuteChanged;

publicRelayCommand(Action execute)

:this(execute, null)

{

} public RelayCommand(Action execute, FunccanExecute)

{if (execute == null)throw new ArgumentNullException("execute");

_execute=execute;

_canExecute=canExecute;

}public RelayCommand(ActionexecuteParam)  //新增重载构造函数 {if(executeParam == null)throw new ArgumentNullException("executeParam");

_executeParam=executeParam;

_canExecute= () => true;

}public RelayCommand(Action executeParam, FunccanExecute)  //新增重载构造函数

{if (executeParam == null)throw new ArgumentNullException("executeParam");

_executeParam=executeParam;

_canExecute=canExecute;

} public bool CanExecute(objectparameter)

{return _canExecute == null ? true: _canExecute();

}

public void Execute(objectparameter)  //新增判断

{if (parameter == null)

_execute();else_executeParam(parameter);

}

public voidRaiseCanExecuteChanged()

{var handler =CanExecuteChanged;if (handler != null)

{

handler(this, EventArgs.Empty);

}

}

}

3.View(可以认为是MainPage.xaml    和原文不一样)

最后在View.cs添加代码

ProductViewModel product = newProductViewModel();

product.ProductId= 111;this.DataContext = product;  //绑定错了的话 COMMAND是不起作用的

以上就是简单的MVVM程序。

PS:下篇文章会接着本文

1.将添加Product集合,绑定到列表

2.给点击ListBox的添加选项改变时的事件(要附加依赖属性,和Button点击事件不同)

3.通过自定义类以JSON获取保存数据到存储空间

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值