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}"/>
相关推荐
执笔论英雄9 小时前
【大模型推理】VLLM 引擎使用
wpf·vllm
LateFrames9 小时前
动画性能比对:WPF / WinUI3 / WebView2
wpf·webview·用户体验·winui3
阿湯哥1 天前
多智能体架构深度解析:企业落地如何选择Skills与SubAgents?
架构·wpf
源之缘-OFD先行者1 天前
自研 WPF 鸟情图表:性能与灵活的双重突破
wpf
Moqiqiuzi1 天前
WPF单实例启动
wpf
Moqiqiuzi1 天前
WPF程序打包成安装包的方法
wpf
码农水水2 天前
国家电网Java面试被问:TCP的BBR拥塞控制算法原理
java·开发语言·网络·分布式·面试·wpf
码农水水2 天前
京东Java面试被问:HTTP/2的多路复用和头部压缩实现
java·开发语言·分布式·http·面试·php·wpf
闻缺陷则喜何志丹2 天前
【C# WPF】TextBox的数据绑定
ui·c#·wpf·mvvm·数据绑定·textbox
码农水水3 天前
得物Java面试被问:大规模数据的分布式排序和聚合
java·开发语言·spring boot·分布式·面试·php·wpf