WPF MVVM技术问题:根据TextBox输入更新Label值(第二次求助)
Hey there, let's get your WPF MVVM setup working correctly so that the Label updates only when both FirstName and LastName TextBoxes are filled in. I've spotted a few key issues in your code—let's fix them one by one:
1. Fix the CanExecute Logic
Right now your AddPersonCanExecute property uses || (OR) instead of && (AND). You want it to return true only when both fields are non-empty, so update that line to:
public bool AddPersonCanExecute { get { return !string.IsNullOrEmpty(_newPerson.FirstName) && !string.IsNullOrEmpty(_newPerson.LastName); } }
(I used !string.IsNullOrEmpty instead of checking against string.Empty to handle whitespace-only inputs better—optional but more robust.)
2. Make Person Implement INotifyPropertyChanged
Your Person class doesn't raise property change notifications, so when you type into the TextBoxes, the ViewModel has no idea that FirstName or LastName has changed. Update your Person.cs like this:
using System.ComponentModel; namespace PracticeUI.Model { public class Person : INotifyPropertyChanged { private string _firstName; private string _lastName; public event PropertyChangedEventHandler PropertyChanged; public string FullName { get { return $"{_firstName} {_lastName}"; } } public string FirstName { get { return _firstName; } set { if (_firstName != value) { _firstName = value; OnPropertyChanged(nameof(FirstName)); OnPropertyChanged(nameof(FullName)); } } } public string LastName { get { return _lastName; } set { if (_lastName != value) { _lastName = value; OnPropertyChanged(nameof(LastName)); OnPropertyChanged(nameof(FullName)); } } } private void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } }
3. Listen to Person's Property Changes in the ViewModel
Now that Person raises property changes, your ViewModel needs to listen to those events so it can update the AddPersonCanExecute status. Update your PersonViewModel.cs:
First, modify the NewPerson property to subscribe/unsubscribe to property change events:
public Person NewPerson { get { return _newPerson; } set { if (_newPerson != null) { // Unsubscribe from old person's events _newPerson.PropertyChanged -= NewPerson_PropertyChanged; } _newPerson = value; if (_newPerson != null) { // Subscribe to new person's events _newPerson.PropertyChanged += NewPerson_PropertyChanged; } OnPropertyChanged(nameof(NewPerson)); OnPropertyChanged(nameof(AddPersonCanExecute)); } }
Then add the event handler to trigger updates when FirstName/LastName changes:
private void NewPerson_PropertyChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == nameof(Person.FirstName) || e.PropertyName == nameof(Person.LastName)) { OnPropertyChanged(nameof(AddPersonCanExecute)); // Tell the command to recheck its CanExecute status CommandManager.InvalidateRequerySuggested(); } }
4. Ensure Your RelayCommand Supports CanExecute Updates
Make sure your RelayCommand class properly handles CanExecuteChanged—here's a standard reliable implementation if you don't have one:
public class RelayCommand : ICommand { private readonly Action<object> _execute; private readonly Func<object, bool> _canExecute; public event EventHandler CanExecuteChanged { add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; } } 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?.Invoke(parameter) ?? true; } public void Execute(object parameter) { _execute(parameter); } }
5. Minor XAML Fix
You have a duplicate "First Name:" label for the LastName TextBox—fix that to avoid confusion:
<Label Content="Last Name:" Grid.Row="3" Grid.Column="1"/>
Final Result
Run the app now:
- When both TextBoxes have text, the Label will show
Trueand the Add button will be enabled - When either field is empty, the Label shows
Falseand the button is disabled
That should get your functionality working exactly as intended!
内容的提问来源于stack exchange,提问作者Teebee15

