第八章-MVVM模式

1、MVVM模式概念

image

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>

 

          image

//在后台代码当中数据上下文绑定视图模型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(); 
        }
    }

 

posted @ 2025-12-16 23:30  nonAny  阅读(37)  评论(0)    收藏  举报