You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF MVVM技术问题:根据TextBox输入更新Label值(第二次求助)

Fix: Trigger Bool Value When Both TextBoxes Are Non-Empty in WPF MVVM

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 True and the Add button will be enabled
  • When either field is empty, the Label shows False and the button is disabled

That should get your functionality working exactly as intended!

内容的提问来源于stack exchange,提问作者Teebee15

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:15:52