WPF Simple Commanding Example

前端 未结 2 1613
时光说笑
时光说笑 2021-01-26 01:12

I try not to post questions like this, but i\'ve really been struggling to find an answer or similar example. I have what I think is a really simple example I\'d like to setup.

2条回答
  •  小鲜肉
    小鲜肉 (楼主)
    2021-01-26 01:34

    how would I implement commanding so that it uses the CanExecute to disable the Add button if the name is already there or the Name field is empty

    I will show how to do the add, the remove is similar and I leave that for you to figure out. First I will show the xaml changes with the button using an AddPerson command:

    
    
    

    We have bound the current edited text to a new property on the View Model named CurrentPerson. This is done because we want to access what the person enters, but also we need the binding updated as the user types. To accomplish that updating, we specify that the binding updates by setting the UpdateSourceTrigger attribute to be PropertyChanged. Otherwise our the CurrentPerson string and ultimately the command Can operation would only fire when the edit text box lost focus.

    ViewModel The viewmodel will subscribe to the AddPerson command. Execution of that will add the user, but also check a can method which returns a boolean whether to enable the button or not. The can will be excecuted when the CurrentPerson property changes where we ultimately call RaiseCanExecuteChanged on the commanding class to have the button check the can method.

    (This VM is abbreviated for the example and based on your full VM)

    public OperationCommand AddPerson { get; set; }
    public string _currentPerson;
    
    public MainViewModel()
    {
     People = new ObservableCollection();
     People.Add(new Person { Name = "jimmy" });
    
                // First Lamda is where we execute the command to add,
                // The second lamda is the `Can` method to enable the button.
     AddPerson = new OperationCommand((o) => People.Add(new Person { Name = CurrentPerson }),
                                      (o) => (!string.IsNullOrWhiteSpace(CurrentPerson) && 
                                              !People.Any(per => per.Name == CurrentPerson)));
    
     // When the edit box text changes force a `Can` check.
     this.PropertyChanged += MainViewModel_PropertyChanged ;
    }
    
    void MainViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName == "CurrentPerson")
            AddPerson.RaiseCanExecuteChanged();
    }
    

    Finally here is the commanding class used which is based on my blog article Xaml: ViewModel Main Page Instantiation and Loading Strategy for Easier Binding.:

    public class OperationCommand : ICommand
    {
    
    #region Variables
    
    Func canExecute;
    Action executeAction;
    
    public event EventHandler CanExecuteChanged;
    
    #endregion
    
    #region Properties
    
    #endregion
    
    #region Construction/Initialization
    
    public OperationCommand(Action executeAction)
        : this(executeAction, null)
    {
    }
    
    public OperationCommand(Action executeAction, Func canExecute)
    {
        if (executeAction == null)
        {
            throw new ArgumentNullException("Execute Action was null for ICommanding Operation.");
        }
        this.executeAction = executeAction;
        this.canExecute = canExecute;
    }
    
    #endregion
    
    #region Methods
    
    public bool CanExecute(object parameter)
    {
        bool result = true;
        Func canExecuteHandler = this.canExecute;
        if (canExecuteHandler != null)
        {
            result = canExecuteHandler(parameter);
        }
    
        return result;
    }
    
    public void RaiseCanExecuteChanged()
    {
        EventHandler handler = this.CanExecuteChanged;
        if (handler != null)
        {
            handler(this, new EventArgs());
        }
    }
    
    public void Execute(object parameter)
    {
        this.executeAction(parameter);
    }
    
    #endregion
    
    }
    
        

    提交回复
    热议问题