第八章-MVVM模式
1、MVVM模式概念

MVVM是一种软件架构模式,它将应用程序分为三个层次:Model(模型),View(视图)和ViewModel(视图模型)
(a)Mode1表示应用程序的数据和业务逻辑
(b)View表示应用程序的用户界面
(c)ViewModel表示View和Model之间的桥梁,它负责处理View的数据绑定和用户交互
2、模型设计(Model)
public class LoginModel:INotifyPropertyChanged { private string account; public string Account { get { return account; } set { account = value; if (PropertyChanged != null) { //如果在ViewModel当中进行更新可不用以下代码 PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Account")); } } } private string password; public string Password { get { return password; } set { password = value; //如果在ViewModel当中进行更新可不用以下代码 if (PropertyChanged != null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Password")); } } } public event PropertyChangedEventHandler? PropertyChanged; }
2、基本界面
Title="LoginView" Height="450" Width="800"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="25"></RowDefinition> <RowDefinition></RowDefinition> </Grid.RowDefinitions> <!--第一行--> <TextBlock Text="用户登录" Width="800" FontSize="20" FontWeight="Light" Background="#0078D4" TextAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock> <!--第二行--> <Grid Grid.Row="1"> <Grid.ColumnDefinitions> <ColumnDefinition Width="180"></ColumnDefinition> <ColumnDefinition></ColumnDefinition> </Grid.ColumnDefinitions> <!--第一列--> <Border Background="LightBlue"> </Border> <!--第二列--> <Border Grid.Column="1" Background="LightCyan"> <Grid HorizontalAlignment="Center" Height="200" Width="200" VerticalAlignment="Center"> <Grid.RowDefinitions> <RowDefinition Height="30"></RowDefinition> <RowDefinition Height="30"></RowDefinition> <RowDefinition Height="auto"></RowDefinition> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="50"></ColumnDefinition> <ColumnDefinition Width="100"></ColumnDefinition> </Grid.ColumnDefinitions> <TextBlock Text="账号" Margin="0,0,0,4"></TextBlock> <!--绑定LoginViewModel视图模型里面LoginM里面的Account属性--> <TextBox Grid.Column="1" Margin="0.4" Text="{Binding Account}"></TextBox> <TextBlock Text="密码" Grid.Row="1" Margin="0,4"></TextBlock> <PasswordBox Grid.Row="1" Grid.Column="1" Margin="0.4" custPwd:PwdHelper.CustPwdProperty="{Binding Password,Mode=TwoWay}" custPwd:PwdHelper.GetOrderProperty="False" ></PasswordBox> <Button Content="登录" Grid.Row="2" Height="30" Width="100" HorizontalAlignment="Center" Command="{Binding loginCommand}" VerticalAlignment="Center" Grid.ColumnSpan="2" FontSize="20" Background="LightBlue" Margin="10"></Button> </Grid> </Border> </Grid> </Grid>

//在后台代码当中数据上下文绑定视图模型LoginViewModel public LoginView() { InitializeComponent(); this.DataContext = new LoginViewModel(); }
3、ViewModel设计
//登录视图模型 public class LoginViewModel:INotifyPropertyChanged { private LoginModel loginM; public LoginModel LoginM=new LoginModel(); //public LoginModel LoginM //{ // get { return loginM; } // set { // loginM = value; // if (PropertyChanged != null) // { // PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("LoginM")); // } // } //} private string account; public string Account { get { return LoginM.Account; } set { LoginM.Account = value; if (PropertyChanged != null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Account")); } } } private string password; public string Password { get { return LoginM.Password; } set { LoginM.Password = value; if (PropertyChanged != null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Password")); } } } // public LoginModel LoginM { get; set; } //模型类的字段 public event PropertyChangedEventHandler? PropertyChanged; private void Login() { string account = this.Account; string password = this.Password; if (account == "123" && password == "321") { MessageBox.Show("登录成功!"); } else { MessageBox.Show("登录失败"); this.Account = ""; this.Password = ""; //viewModel.LoginM.Account = ""; //viewModel.LoginM.Password = ""; } } public LoginCommand loginCommand { get { LoginCommand command = new LoginCommand(); command.Do = Login; return command; } } }
Passoword附加属性类
//附加属性 public class PwdHelper { //包装 public static string GetCustPwdProperty(DependencyObject obj) { return (string)obj.GetValue(CustPwdProperty); } public static void SetCustPwdProperty(DependencyObject obj, string value) { obj.SetValue(CustPwdProperty, value); } // 定义、注册 public static readonly DependencyProperty CustPwdProperty = DependencyProperty.RegisterAttached("CustPwdProperty", typeof(string), typeof(PwdHelper), new PropertyMetadata("", OnCustPwdPropertyChanged)); //当附加属性变化时将PasswordBox的Password修改为附加属性的值 private static void OnCustPwdPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { string pwd = (string)e.NewValue; PasswordBox passwordBox = d as PasswordBox;//弱转换 if (passwordBox != null) { if (passwordBox.Password != pwd) { passwordBox.Password = pwd; } } } //当PasswordBox的Password变化时将附加属性修改为Password的值 public static bool GetOrderProperty(DependencyObject obj) { return (bool)obj.GetValue(OrderProperty); } public static void SetGetOrderProperty(DependencyObject obj, bool value) { obj.SetValue(OrderProperty, value); } // Using a DependencyProperty as the backing store for MyProperty. This enables animation, styling, binding, etc... public static readonly DependencyProperty OrderProperty = DependencyProperty.RegisterAttached("OrderProperty", typeof(bool), typeof(PwdHelper), new PropertyMetadata(true, OnOrderPropertyChanged)); private static void OnOrderPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { PasswordBox passwordBox = d as PasswordBox; if (passwordBox != null) { passwordBox.PasswordChanged -= OnPasswordChanged; passwordBox.PasswordChanged += OnPasswordChanged; } } private static void OnPasswordChanged(object sender, RoutedEventArgs e) { PasswordBox dp = sender as PasswordBox; SetCustPwdProperty(dp, dp.Password); } } }
命令定义
public class LoginCommand : ICommand { public Action Do { get; set; } public event EventHandler? CanExecuteChanged; public bool CanExecute(object? parameter) { return true; } public void Execute(object? parameter) { Do?.Invoke(); } }
浙公网安备 33010602011771号