初识MVVM
来源:互联网 发布:淘宝机器人自动回复 编辑:程序博客网 时间:2024/05/21 22:43
MVVM分解:
M-> 源数据一堆get,set方法,对应Java中,JavaBean
V-> 窗体,显示界面
VM-> 业务逻辑层,对窗体的逻辑响应,及数据传输的处理。
这样做的优点:
窗体改变,只需变动窗体样式,绑定对应的数据及响应事件(VM)。
VM只需处理逻辑改变
M只需添加数据或删除数据,及将数据变化反馈给UI
MVVM需要实现两个关键接口。
A) ICommand接口,此接口用于实现界面响应事件的委托
B) INotifyPropertyChanged接口,此接口用于实现 界面和数据源同步变化
以登录窗体为例,实现
A)修改Module中数据,改变界面显示
B)修改界面输入数据,同步Module中的数据
1)新建工程,KnowXAML
主界面类.cs如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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.Navigation;
using System.Windows.Shapes;
using KnowXAML.ModuleView;
namespace KnowXAML
{
///<summary>
/// Interaction logic for MainWindow.xaml
///</summary>
public partial class MainWindow :Window
{
public MainWindow()
{
InitializeComponent();
}
}
}
2)新建ICommand界面命令代理类 UICommand. UICommand用于实现空间响应事件的代理。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
namespace KnowXAML.DelegateCommand
{
classUICommand :ICommand
{
///<summary>
///判断控件是否可用
///</summary>
Func<object,bool> canExecute;
///<summary>
///执行方法
///</summary>
Action<object> executeAction;
bool canExecuteCache;
public event EventHandler CanExecuteChanged;
public UICommand(Action<object> executeAction, Func<object,bool> canExecute)
{
this.executeAction = executeAction;
this.canExecute = canExecute;
}
bool ICommand.CanExecute(objectparameter)
{
bool temp = canExecute(parameter);
if (canExecuteCache != temp)
{
canExecuteCache = temp;
if (CanExecuteChanged != null)
CanExecuteChanged(this,newEventArgs());
}
return canExecuteCache;
}
void ICommand.Execute(object parameter)
{
executeAction(parameter);
}
}
}
3)创建类UINotifier,实现界面数据同步接口INotifyPropertyChanged。此类用于同步界面和底层类(Bean)数据。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
namespaceKnowXAML.DelegateNotifer
{
public abstract class UINotifier :INotifyPropertyChanged
{
#region INotifyPropertyChanged
publiceventPropertyChangedEventHandler PropertyChanged;
#endregion
#region Protected
protectedvirtualvoid OnPropertyChanged(stringpropertyName)
{
if (PropertyChanged !=null)
PropertyChanged(this,newPropertyChangedEventArgs(propertyName));
}
#endregion
}
}
4)创建底层数据类(Bean),User,继承类DelegateNotifer
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Threading.Tasks;
using KnowXAML.DelegateNotifer;
namespace KnowXAML.Module
{
publicclassUser :UINotifier
{
privatestring userName;
publicstring Name
{
get
{
return userName;
}
set
{
userName =value;
OnPropertyChanged("Name");
}
}
privatestring userPassword;
public string Password
{
get
{
return userPassword;
}
set
{
userPassword =value;
OnPropertyChanged("Password");
}
}
}
}
5)创建ModuleView类,用于User类和界面的数据桥接。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using KnowXAML.Module;
using KnowXAML.DelegateCommand;
using KnowXAML.DelegateNotifer;
namespace KnowXAML.ModuleView
{
classUserModuleView
{
publicUser user {get;set; }
public UICommand uiCommand { get;set; }
public UserModuleView()
{
this.user =newUser();
this.uiCommand =new UICommand(SetUserInfo, arg=>true); //指定命令外//部接口uiCommand对应函数为SetUserInfo。uiCommand用于XMAL中配置
}
public void SetUserInfo(object parm)
{
user.Name ="zhangsan";
user.Password ="123124";
}
public User userMode
{
get
{
return user;
}
set
{
if (user == value)
return;
user =value;
}
}
}
}
6)添加控件,修改XMAL,添加数据绑定及响应事件。黄色背景处为添加数据源,及响应事件项。
XMAL格式如下:
<Window x:Class="KnowXAML.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:KnowXAML"
xmlns:vm="clr-namespace:KnowXAML.ModuleView"
mc:Ignorable="d"
Title="MainWindow"Height="277.407" Width="525">
<Window.DataContext>
<vm:UserModuleView />
</Window.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="118*"/>
<ColumnDefinition Width="401*"/>
</Grid.ColumnDefinitions>
<GroupBox x:Name="groupBox"Header="GroupBox" HorizontalAlignment="Left"Margin="10,26,0,-0.4"VerticalAlignment="Top" Height="224"Width="498" Background="AliceBlue"Grid.ColumnSpan="2">
<Grid HorizontalAlignment="Left"Margin="10,10,-3.2,34.4" Width="478">
<Grid.ColumnDefinitions>
<ColumnDefinitionWidth="115*"/>
<ColumnDefinitionWidth="363*"/>
</Grid.ColumnDefinitions>
<Label x:Name="lblUserName"Content="UserName:"HorizontalAlignment="Left" Margin="31,24,0,0"VerticalAlignment="Top" Width="86"FontSize="16" Grid.ColumnSpan="2"/>
<TextBox x:Name="txtUserName"HorizontalAlignment="Left" Height="27" Margin="20.587,29,0,0" Text="{Binding Path= userMode.Name}"TextWrapping="Wrap" VerticalAlignment="Top"Width="251" FontSize="16"Grid.Column="1"/>
<Label x:Name="lblPassword"Content="Password:" FontSize="16" HorizontalAlignment="Left"Margin="36,82,0,0"VerticalAlignment="Top"RenderTransformOrigin="-0.205,0.338"Grid.ColumnSpan="2"/>
<TextBox x:Name="txtPassword"HorizontalAlignment="Left" FontSize="16"Text="{Binding Path= userMode.Password}" Height="25"Margin="20.587,88,0,0"TextWrapping="Wrap" VerticalAlignment="Top"Width="251" Grid.Column="1"/>
<Button x:Name="btnCancel"Content="Cancel"HorizontalAlignment="Left" Margin="62.587,132,0,0"VerticalAlignment="Top" Width="75"Grid.Column="1"/>
<Button x:Name="btnOK" Command="{Binding uiCommand}" Content="OK"HorizontalAlignment="Left" Margin="196.587,132,0,0"VerticalAlignment="Top" Width="75"Grid.Column="1"/>
</Grid>
</GroupBox>
</Grid>
</Window>
7)运行界面
初始化界面:
点击“OK”后界面
修改UserName后,点击“OK”
如果觉得我写的还不错,请关注我的微信:
- 初识MVVM
- MVVM初识
- MVVM初识
- 初识MVVM
- 初识MVVM的心得
- MVVM
- MVVM
- MVVM
- MVVM
- MVVM
- MVVM
- MVVM
- MVVM
- mvvm
- MVVM
- MVVM
- mvvm
- MVVM
- 如何理解接口这个抽象的概念?
- jQuery——事件
- 关于端口聚合或端口聚合称呼的误区
- kali源代码简单说明
- HashMap-数组+链表集合
- 初识MVVM
- 学习Glide--Android图片加载框架
- leetcode.array--1. Two Sum
- 使用Spring AOP实现MySQL数据库读写分离案例分析
- 内存的理解
- java.lang.VerifyError: Verifier rejected class com.xx.xx
- 贝叶斯与朴素贝叶斯分类器
- springmvc中使用thymeleaf乱码完整方案
- ubuntu下python+tornado+supervisor+nginx部署