【WPF】MVVM极其简单的例子
目的:通过例子了解、理解MVVM的基本结构。
Model
namespace WpfStudy.Model
{
public class UserModel
{
public string Name { get; set; }
}
}
ViewModel
namespace WpfStudy.ViewModel
{
public class MainVM : NotifyPropBase
{
public MainVM(MainWindow view)
{
View = view;
}
private MainWindow View { get; set; }
private UserModel _userModel;
public UserModel User
{
get
{
if (_userModel == null)
{
_userModel = new UserModel();
}
return _userModel;
}
set { _userModel = value; Notify(); }
}
public RelayCmd ClickCmd => new RelayCmd((a) =>
{
MessageBox.Show(User.Name);
User.Name = null;
User = User;//或者使用Notify("User");
});
public RelayCmd CloseCmd => new RelayCmd((a) =>
{
View.Close();
});
}
}
View
xaml
<Window.Resources>
<Style TargetType="Button">
<Setter Property="Width" Value="100"/>
<Setter Property="Height" Value="30"/>
<Setter Property="Margin" Value="0,30,0,0"/>
</Style>
</Window.Resources>
<StackPanel Margin="20">
<TextBox Text="{Binding User.Name}" Width="100" Height="40" Margin="0,0,0,20" FontSize="30"/>
<Button Content="清空" Command="{Binding ClickCmd}"/>
<Button Content="关闭窗口" Command="{Binding CloseCmd}"/>
</StackPanel>
cs
namespace WpfStudy
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new MainVM(this);
}
}
}
两个工具类
监听属性变化
public class NotifyPropBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void Notify([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
监听命令
public class RelayCmd : ICommand
{
public RelayCmd(Action<object> execute)
{
_execute = execute;
}
readonly Action<object> _execute;
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter) => true;
public void Execute(object parameter)
{
_execute?.Invoke(parameter);
}
}
思考
-
Model里面就写CLR属性,不搞属性值变化的监听。
-
View的cs代码也要简洁,只显式留一个构造函数,不留其他属性和方法。
-
业务交互功能集中在ViewModel中。
-
是在ViewModel中对Model进行监听设置,所以Model内的属性修改后,需要显式重新赋值一下Model,本质上是在ViewModel中调用Notify()并传递Model类型的属性名。
-
还可以再VM中增加常用的Model属性,给View提供绑定,实际用的还是Model中的数据。