界面参数的传递,界面参数是如何从前台传送到后台的。
param
参数是从界面传递到命令的。这个过程通常涉及以下几个步骤:
-
数据绑定:界面元素(如按钮)的
Command
属性绑定到视图模型中的RelayCommand
实例。同时,界面元素的CommandParameter
属性(如果有的话)可以绑定到视图模型中的某个属性或直接设置为一个静态值。这个CommandParameter
就是传递给RelayCommand
的param
参数。 -
命令触发:当用户与界面元素交互(例如点击按钮)时,会触发绑定的命令。WPF 框架会调用命令的
Execute
方法(如果命令可执行)或CanExecute
方法(以检查命令是否可执行)。 -
参数传递:在命令触发时,
CommandParameter
的值被传递给命令的Execute
和CanExecute
方法作为param
参数。 -
参数使用:在
RelayCommand
的 lambda 表达式中,param
被转换为ViewModel
类型(这里假设传递的参数实际上是ViewModel
类型的实例或可以安全地转换为ViewModel
类型)。然后,这个转换后的ViewModel
实例被传递给SaveUser
方法或IsUserSaveEnabled
方法。 -
属性访问:在
SaveUser
或IsUserSaveEnabled
方法中,就可以安全地访问ViewModel
实例的属性,如UserName
。由于这些方法接收的是已经转换为正确类型的ViewModel
实例,因此可以直接读取其属性。
一开始无法点击登录
然后点击账户历史自动填入
填入其他内容后再点击登录,账户历史会更新
ViewModel代码
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,则返回 falsereturn false;}// 现在可以安全地访问 viewModel.UserNamereturn !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代码:
<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>