WPF 界面命令绑定(MVVM结构)

1.创建模型数据类(M)

csharp 复制代码
    /// <summary>
    /// 数据模型
    /// </summary>
    public class LoginDataModel
    {
        // 用户名
        private string _userName;

        public string UserName
        {
            get { return _userName; }
            set
            {
                _userName = value;
            }
        }

        // 密码
        private string _passWord;

        public string PassWord
        {
            get { return _passWord; }
            set
            {
                _passWord = value;               
            }
        }
    }

2.命令转发类实现接口(ICommand)

csharp 复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;

namespace WPF_LoginUI
{
    /// <summary>
    /// 命令转发
    /// </summary>
    public class RelayCommand : ICommand
    {
        /// <summary>
        /// 命令是否能够执行
        /// </summary>
        private readonly Func<bool> _canExecute;

        /// <summary>
        /// 需要执行的方法
        /// </summary>
        private readonly Action _execute;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="execute"></param>
        /// <param name="canExecute"></param>
        public RelayCommand(Action execute, Func<bool> canExecute)
        {
            _canExecute = canExecute;
            _execute = execute;
        }

        /// <summary>
        /// 事件句柄
        /// </summary>
        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();
        }

        // 实现接口 执行命令
        public void Execute(object parameter)
        {
            _execute();
        }
    }
}

3.创建视图模型类(VM)

csharp 复制代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;

namespace WPF_LoginUI
{
    /// <summary>
    /// MVVM 架构的  VM(视图模型类)
    /// </summary>
    public class LoginViewModel : INotifyPropertyChanged
    {
        /// <summary>
        ///  数据模型(存放数据)
        /// </summary>
        private LoginDataModel loginData;
        // 父窗体
        private MainWindow _mainWindow;

        public LoginViewModel(MainWindow mainWindow) 
        {
            _mainWindow = mainWindow;
            loginData = new LoginDataModel();
        }

        // 属性变化时 通知界面 
        public event PropertyChangedEventHandler PropertyChanged;
        private void RaisePropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(propertyName));
        }

        // 开放被绑定的数据

        // 被绑定的属性 用户名
        public string UserName
        {
            get { return loginData.UserName; }
            set
            {
                loginData.UserName = value;
                // 通知界面 属性发生变化
                RaisePropertyChanged("UserName");
            }
        }

        // 被绑定的属性 密码
        public string PassWord
        {
            get { return loginData.PassWord; }
            set
            {
                loginData.PassWord = value;
                // 通知界面 属性发生变化
                RaisePropertyChanged("PassWord");
            }
        }

        /// <summary>
        /// 事件-换成命令绑定方式
        /// </summary>

        // 登录函数
        private void LoginFunc()
        {
            if (UserName == "WPF" && PassWord == "123")
            {   // 弹出一个新的界面 ctrl+ k + d
                //MessageBox.Show("OK");
                IndexWindow indexWindow = new IndexWindow();
                indexWindow.Show();

                // 隐藏登录界面
                _mainWindow.Hide();
            }
            else
            {// 警告框
                MessageBox.Show("输入的用户名或密码不正确");

                UserName = "";
                PassWord = "";
            }
        }

        // 是否执行函数
        private bool CanLoginExecute()
        {
            return true;
        }

        // 界面绑定命令
        public ICommand LoginAction 
        {
            get 
            {
                return new RelayCommand(LoginFunc, CanLoginExecute);
            } 
        }
    }
}

4.设置上下文关联

csharp 复制代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WPF_LoginUI
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            // 为界面设置 绑定数据
            this.DataContext = new LoginViewModel(this); 
        }

    }
}

5.界面绑定

csharp 复制代码
<!-- 绑定对象的属性  UserName -->
<TextBox Text="{Binding UserName}" Grid.Row="0" Grid.Column="1" Margin="2"/>
<!-- 绑定对象的属性  PassWord -->
<TextBox Text="{Binding PassWord}" Grid.Row="1" Grid.Column="1" Margin="2"/>

<!-- 命令绑定 登录按钮 执行函数 LoginAction-->
<Button x:Name="BtnLogin" Grid.Row="3" Grid.Column="0" Content="登录" Grid.ColumnSpan="2" Command="{Binding LoginAction}"/>
相关推荐
做个文艺程序员10 小时前
MQ第12篇:AI原生消息架构演进:从MQ到事件驱动的全链路设计
架构·消息队列·wpf·事件驱动架构·ai-native·cqrs
donk13142 天前
React Native for OpenHarmony 实战:三方库 react-native-circular-action-menu 的鸿蒙化适配指南
javascript·分布式·react native·react.js·wpf·harmonyos
donk13143 天前
React Native for OpenHarmony 实战:三方库 react-native-step-indicator 的鸿蒙化适配指南
分布式·react native·react.js·wpf·harmonyos
He BianGu3 天前
【笔记】WPF中RenderOptions类的详细功能
笔记·wpf
VidDown3 天前
上线三个月后的第一次事故:一个 Django 服务的日志、监控与故障复盘
数据库·python·django·wpf·音视频·视频编解码
He BianGu3 天前
【笔记】WPF中CachingHint的功能
笔记·wpf
He BianGu3 天前
【笔记】在WPF中BitmapScalingMode的作用
笔记·wpf
Vae_Mars4 天前
幂等性学习笔记
笔记·学习·wpf
samble5 天前
从零搭建灌装监控系统(十九):单元测试实战,xUnit + 内存SQLite + 反射测试私有方法
c#·wpf·mvvm·modbus·工业控制
光泽雨6 天前
路由概念和路由事件 继承链路 RadioButton的事件解析
wpf