MVVM架构是一种基于数据驱动的软件开发架构,它将数据模型(Model)、视图(View)和视图模型(ViewModel)三者进行分离,使得开发者可以更加专注于各自领域的开发。其中,Model负责存储和管理数据,View负责数据的展示,而ViewModel则作为Model和View之间的桥梁,负责数据的双向绑定和业务逻辑的处理。
MVVM架构的特点
- 数据驱动:MVVM架构的核心是数据驱动,当数据发生变化时,视图会自动更新,反之亦然。这种双向数据绑定的机制大大减少了开发者在视图和数据之间手动同步的工作量。
- 分离关注点:通过将Model、View和ViewModel三者进行分离,开发者可以更加专注于各自领域的开发,提高了代码的可维护性和可重用性。
- 视图与业务逻辑解耦:ViewModel负责处理业务逻辑,而View只负责展示数据,这种设计使得视图和业务逻辑之间的耦合度大大降低,提高了代码的可读性和可测试性。
实现效果 :
阶段一:代码创建文件放置,搭建出INotifyPropertyChanged进行前后台数据更新
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="100"/>
<RowDefinition Height="150"/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Border BorderThickness="1" BorderBrush="Black" Grid.Row="1" Height="30" Width="200" VerticalAlignment="Top" >
<TextBox Text="{Binding UserName}"/>
</Border>
<Border BorderThickness="1" BorderBrush="Black" Grid.Row="1" Height="30" Width="200" VerticalAlignment="Top" Margin="0,40,0,0" >
<TextBox Text="{Binding PassWord}" />
</Border>
<Button Grid.Row="1" Height="30" Width="200" VerticalAlignment="Bottom" Content="按钮" Click="Button_Click"/>
</Grid>
namespace WpfApp_libarymassage
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window, INotifyPropertyChanged
{
public MainWindow()
{
this.DataContext = this;
InitializeComponent();
}
private string _UserName;
public string UserName
{
get { return _UserName; }
set { _UserName = value;
OnPropertyChanged("UserName");
}
}
private string _PassWord;
public string PassWord
{
get { return _PassWord; }
set { _PassWord = value;
OnPropertyChanged(PassWord);
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
private void Button_Click(object sender, RoutedEventArgs e)
{
//string useName = textUserName.Text;
//string passWord = textPassWord.Text;
if (UserName == "AA" && PassWord == "123456" )
{
MessageBox.Show("Loding Successful");
}
else
{
MessageBox.Show("Load Fail");
UserName = "";
PassWord = "";
}
}
}
}
阶段二:创建Model和ViewModel文件,降低数据的关联
LoginModel.cs文件
public class LoginModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
private string _UserName;
public string UserName
{
get { return _UserName; }
set
{
_UserName = value;
OnPropertyChanged("UserName");
}
}
private string _PassWord;
public string PassWord
{
get { return _PassWord; }
set
{
_PassWord = value;
OnPropertyChanged(PassWord);
}
}
}
LoginViewModel.cs
public class LoginViewModel
{
private LoginModel _loginM; //创建LoginModel类型的变量_loginM
public LoginModel LoginM
{
get {
if (_loginM == null) //如果没有实列化LoginModel,实列化LoginModel
_loginM = new LoginModel();
return _loginM; }
set { _loginM = value; }
}
}
XAM文件
public partial class MainWindow : Window
{
LoginViewModel loginViewModel; //创建变量LoginViewModel类型的变量loginViewModel
public MainWindow()
{
loginViewModel = new LoginViewModel(); //loginViewModel进行实列化
this.DataContext = loginViewModel; //绑定上下文
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
//因为我们实列话了LoginViewModel(),绑定的的变量是在LoginViewModel中的LoginM中
//所以变量连接为loginViewModel.LoginM.UserName
if (loginViewModel.LoginM.UserName == "AA" && loginViewModel.LoginM.PassWord == "123456" )
{
MessageBox.Show("Loding Successful");
}
else
{
MessageBox.Show("Load Fail");
loginViewModel.LoginM.UserName = "";
loginViewModel.LoginM.PassWord = "";
}
}
}
<Border BorderThickness="1" BorderBrush="Black" Grid.Row="1" Height="30" Width="200" VerticalAlignment="Top" >
<TextBox Text="{Binding LoginM.UserName}"/>
</Border>
<Border BorderThickness="1" BorderBrush="Black" Grid.Row="1" Height="30" Width="200" VerticalAlignment="Top" Margin="0,40,0,0" >
<TextBox Text="{Binding LoginM.PassWo
阶段三:将按钮放入ViewModel中
ICommand接口调用
RelayCommander.cs
internal class RelayCommander:ICommand
{
readonly Func<bool> _canExecute; //命令是否能够执行
readonly Action _execute; //命令需要执行的方法
public RelayCommander(Action action, Func<bool> canExecute)
{
_execute =action;
_canExecute =canExecute;
}
public bool CanExecute(object parameter)
{
if (_canExecute != null)
{
return true;
}
return _canExecute();
}
public void Execute(object parameter)
{
_execute();
}
public event EventHandler CanExecuteChanged
{
add
{
if (_canExecute != null)
{
CommandManager.RequerySuggested += value;
}
}
remove
{
if ( _canExecute != null)
{
CommandManager.RequerySuggested -= value;
}
}
}
}
在ViewModel中调用接口
public class LoginViewModel
{
private LoginModel _loginM; //创建LoginModel类型的变量_loginM
public LoginModel LoginM
{
get {
if (_loginM == null) //如果没有实列化LoginModel,实列化LoginModel
_loginM = new LoginModel();
return _loginM; }
set { _loginM = value; }
}
//登录按钮方法
void LoginFunc()
{
if (LoginM.UserName == "AA" && LoginM.PassWord == "123456")
{
MessageBox.Show("Loding Successful");
}
else
{
MessageBox.Show("Load Fail");
LoginM.UserName = "";
LoginM.PassWord = "";
}
}
bool CanLoginExcute() { return true; }
//命令绑定至按钮
public ICommand LoginButton //LoginButton参数为按钮Command绑定的参数
{
get
{
return new RelayCommander(LoginFunc, CanLoginExcute);
}
}
}
xaml
public partial class MainWindow : Window
{
LoginViewModel loginViewModel; //创建变量LoginViewModel类型的变量loginViewModel
public MainWindow()
{
loginViewModel = new LoginViewModel(); //loginViewModel进行实列化
this.DataContext = loginViewModel; //绑定上下文
InitializeComponent();
}
}
<Button Grid.Row="1" Height="30" Width="200" VerticalAlignment="Bottom" Content="按钮" Command="{Binding LoginButton}"/>