58.界面参数传递给Command C#例子 WPF例子

界面参数的传递,界面参数是如何从前台传送到后台的。

param 参数是从界面传递到命令的。这个过程通常涉及以下几个步骤:

  1. 数据绑定 :界面元素(如按钮)的 Command 属性绑定 到视图模型中的 RelayCommand 实例。同时,界面元素的 CommandParameter 属性(如果有的话)可以绑定 到视图模型中的某个属性或直接设置为一个静态值 。这个 CommandParameter 就是传递给 RelayCommandparam 参数。

  2. 命令触发 :当用户与界面元素交互(例如点击按钮)时,会触发绑定的命令。WPF 框架会调用命令的 Execute 方法(如果命令可执行)或 CanExecute 方法(以检查命令是否可执行)。

  3. 参数传递 :在命令触发时,CommandParameter 的值 被传递给命令的 ExecuteCanExecute 方法作为 param 参数

  4. 参数使用 :在 RelayCommand 的 lambda 表达式中,param 被转换为 ViewModel 类型(这里假设传递的参数实际上是 ViewModel 类型的实例 或可以安全地转换为 ViewModel 类型)。然后,这个转换后的 ViewModel 实例被传递给 SaveUser 方法或 IsUserSaveEnabled 方法。

  5. 属性访问 :在 SaveUserIsUserSaveEnabled 方法中,就可以安全地访问 ViewModel 实例的属性,如 UserName 。由于这些方法接收的是已经转换为正确类型的 ViewModel 实例,因此可以直接读取其属性。

一开始无法点击登录

然后点击账户历史自动填入

填入其他内容后再点击登录,账户历史会更新

ViewModel代码

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

namespace Icommand练习
{
    class ViewModel:INotifyPropertyChanged
    {


        private string _userName;
        public string UserName
        {
            get { return _userName; }
            set { _userName = value; OnPropertyChanged(nameof(UserName)); }
        }

        private string _email;
        public string Email
        {
            get { return _email; }
            set { _email = value; OnPropertyChanged(nameof(Email)); }
        }

        private string _tempUserName;
        public string TempUserName
        {
            get { return _tempUserName; }
            set { _tempUserName = value; }
        }
        private string _tempEmail;
        public string TempEmail
        {
            get { return _tempEmail; }
            set { _tempEmail = value; }
        }



        public ICommand SaveCommand { get; private set; }

        public ViewModel()
        {
            SaveCommand = new RelayCommand(param => SaveUser((ViewModel)param), param => IsUserSaveEnabled((ViewModel)param));
            Button2Command=new RelayCommand(param => Button2Click(), param=>true);
            this.TempUserName = "网易";
            this.TempEmail = "123456@163.com";
        }

        private void SaveUser(ViewModel user)
        {
            // 在这里实现保存用户的逻辑,比如调用API或保存到数据库
            // 这里只是简单打印用户信息
            MessageBox.Show($"Saving user: UserName={user.UserName}, Email={user.Email}");
            user.TempUserName = _userName;
            user.TempEmail = _email;

        }

        private bool IsUserSaveEnabled(ViewModel viewModel)
        {
            if (viewModel == null)
            {
                // 如果 param 不是 ViewModel 类型或者为 null,则返回 false
                return false;
            }

            // 现在可以安全地访问 viewModel.UserName
            return !string.IsNullOrEmpty(viewModel.UserName);
        }


        public ICommand Button2Command {  get; }



        public void Button2Click()
        {
            UserName = TempUserName;
            Email = TempEmail;
        }








        //固定
        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

    }

    //public class RelayCommand : ICommand
    //{
    //    private readonly Action<object> _execute;
    //    public event EventHandler CanExecuteChanged;

    //    public RelayCommand(Action<object> execute) => _execute = execute;

    //    public bool CanExecute(object parameter) => true; // 总是可执行(简化)
    //    public void Execute(object parameter) => _execute(parameter);
    //}

    public class RelayCommand : ICommand
    {
        private readonly Action<object> _execute;
        private readonly Func<object, bool> _canExecute;

        public RelayCommand(Action<object> execute, Func<object, bool> canExecute = null)
        {
            _execute = execute ?? throw new ArgumentNullException(nameof(execute));
            _canExecute = canExecute;
        }

        public bool CanExecute(object parameter)
        {
            return _canExecute == null || _canExecute(parameter);
        }

        public void Execute(object parameter)
        {
            _execute(parameter);
        }

        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

        // 可以在这里添加额外的逻辑来处理 CanExecuteChanged 事件的触发,但上面的实现已经足够用于大多数场景。
    }

}

XAMl代码:

XML 复制代码
<Window x:Class="Icommand练习.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Icommand练习"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <StackPanel>
        <TextBox Text="{Binding UserName, UpdateSourceTrigger=PropertyChanged}" />
        <TextBox Text="{Binding Email, UpdateSourceTrigger=PropertyChanged}" />
        <Button Content="登录" Command="{Binding SaveCommand}" CommandParameter="{Binding}" />
        <Button Command="{Binding Button2Command}" Content="账户历史"/>
    </StackPanel>
</Window>
相关推荐
qq_447663051 小时前
java-----多线程
java·开发语言
a辰龙a1 小时前
【Java报错解决】警告: 源发行版 11 需要目标发行版 11
java·开发语言
听海边涛声1 小时前
JDK长期支持版本(LTS)
java·开发语言
IpdataCloud1 小时前
Java 获取本机 IP 地址的方法
java·开发语言·tcp/ip
MyMyMing1 小时前
Java的输入和输出
java·开发语言
Easonmax1 小时前
【javaSE】内部类(来自类和对象的补充)
开发语言·javascript·ecmascript
云夏之末1 小时前
【Java报错已解决】java.lang.UnsatisfiedLinkError
java·开发语言
li星野3 小时前
QT:图像上绘制图形
开发语言·qt
花落已飘3 小时前
RK3568中使用QT opencv(显示基础图像)
开发语言·qt·opencv
Mr_Xuhhh3 小时前
进程间通信
android·java·服务器·开发语言·数据库