界面參數的傳遞,界面參數是如何從前臺傳送到后臺的。
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>