WPF MVVM模式构建项目
什么是MVVM模式?
MVVM是Model-View-ViewModel的简写,Model就是模型,View就是视图,ViewModel就是View和Model之间解耦和传递消息的中间层。MVVM采用双向数据绑定,View中数据变化将自动反映到ViewModel上,反之,Model中数据变化也将会自动展示在View上。通过MVVM模式使得View和Model上的修改相互不影响,方便程序分工,测试和维护。
基于WPF的MVVM模式的框架有很多种,流行的是MvvmLight(轻量级Mvvm框架,现已不更新)和Prism(大型Mvvm框架),本篇不使用框架来实现MVVM模式构建项目,了解WPF内部实现机理。使用MVVM框架请参考:
MvvmLight:WPF MVVMLight介绍和使用(1)_无熵~的博客-CSDN博客
Prism:WPF Prism介绍和简单实例_prism.wpf_无熵~的博客-CSDN博客
创建一个基于MVVM模式的登录项目,实现方式:
首先建立相应的文件夹:一个ViewModel,一个View,一个Model。在ViewModel里面有一个基础的通知类:NotifyPropertyChanged,这个类继承自INotifyPropertyChanged(这个类是通知的基础类,当事件执行时,会将相应的值显示在绑定的控件上);一个命令通知类:DelegateCommand,实现ICommand接口,用于消息传递。
Model类:如果想让属性绑定到其他数据,可以将属性定义成依赖属性并让类继承DependencyObject类。
public class User:DependencyObject
{
public string Name
{
get { return (string)GetValue(NameProperty); }
set { SetValue(NameProperty, value); }
}
// Using a DependencyProperty as the backing store for Name. This enables animation, styling, binding, etc...
public static readonly DependencyProperty NameProperty =
DependencyProperty.Register("Name", typeof(string), typeof(User), new PropertyMetadata(null));
public string Password
{
get { return (string)GetValue(PasswordProperty); }
set { SetValue(PasswordProperty, value); }
}
public static readonly DependencyProperty PasswordProperty =
DependencyProperty.Register("Password", typeof(string), typeof(User), new PropertyMetadata(null));
}
View页面实现:
<Window x:Class="WpfMvvmDemo.View.LoginWindow"
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:WpfMvvmDemo.View"
mc:Ignorable="d"
Title="{Binding Info}" Height="450" Width="800" WindowStartupLocation="CenterScreen">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBox x:Name="txtUser" Text="{Binding User.Name,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"
Width="300" Height="40"/>
<TextBox x:Name="txtPassword" Text="{Binding User.Password,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"
Grid.Row="1" Width="300" Height="40" />
<Button Content="Query" Command="{Binding LoginCommand}" CommandParameter="login"
Grid.Row="2" Width="200" Height="30" />
</Grid>
</Window>
View页面指定数据源:
/// <summary>
/// LoginWindow.xaml 的交互逻辑
/// </summary>
public partial class LoginWindow : Window
{
public LoginWindow()
{
InitializeComponent();
this.DataContext = new UserVM();
}
}
ViewModel类:
public class UserVM: NotifyPropertyChanged
{
private string info;
public string Info
{
get { return info; }
set
{
info = value;
OnPropertyChanged();
}
}
public UserVM()
{
User = new User()
{
Name = "admin",
Password = "123456"
};
Info = "用户登录";
}
private User user;
public User User
{
get { return user; }
set
{
user = value;
OnPropertyChanged();
//NotifyPropertyChanged("User");
}
}
public ICommand LoginCommand
{
get { return new DelegateCommand(LoginCommandEvent, CanLogin); }
}
private void LoginCommandEvent(Object o)
{
MessageBox.Show(string.Format($"用户:{User.Name},参数:{o.ToString()}"));
}
private bool CanLogin(Object o)
{
if(o!=null)
{
return true;
}
return false;
}
}
ViewModel中NotifyPropertyChanged类定义,继承自INotifyPropertyChanged。
public class NotifyPropertyChanged : INotifyPropertyChanged
{
/// <summary>
/// 实现接口
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// 属性变更事件
/// </summary>
/// <param name="Path">事件源</param>
public void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
ViewModel中DelegateCommand类定义,实现ICommand接口。
public class DelegateCommand : ICommand
{
public event EventHandler CanExecuteChanged
{
add
{
if (_canExecute != null)
{
CommandManager.RequerySuggested += value;
}
}
remove
{
if (_canExecute != null)
{
CommandManager.RequerySuggested -= value;
}
}
}
public bool CanExecute(object parameter)
{
if (_canExecute == null)
{
return true;
}
return _canExecute(parameter);
}
public void Execute(object parameter)
{
if (_execute != null && CanExecute(parameter))
{
_execute(parameter);
}
}
private Func<object, bool> _canExecute;
private Action<object> _execute;
public DelegateCommand(Action<object> execute, Func<object, bool> canExecute)
{
_execute = execute;
_canExecute = canExecute;
}
public DelegateCommand(Action<object> execute) :
this(execute, null)
{
}
}
实例链接:https://download.csdn.net/download/lvxingzhe3/87669239