How do I pass a variable as a CommandParameter

佐手、 提交于 2019-11-28 01:55:20
Dylan Meador

Is the CommandParameter always null or are you only checking the first time it is being executed?

It appears that the order in which you declare your properties matters in this case since setting the Command property causes the CanExecute to fire immediately before the CommandParameter has been set.

Try moving the CommandParameter property before the Command property:

<Button Content="Edit" HorizontalAlignment="Right" Height="20"  Width="80"
 CommandParameter="{Binding PersonModelProp}" 
 Command="{Binding EditPersonCommand}" />

Also, see here and here.

Edit

To ensure that your events are being raised properly you should raise the CanExecuteChanged event when the PersonModelProp value changes.

The Command:

public class EditPersonCommand : ICommand
{
  public bool CanExecute(object parameter)
  {
     PersonModel p = parameter as PersonModel;
     return p != null && p.Age > 0;
  }

  public event EventHandler CanExecuteChanged;

  public void Execute(object parameter) 
  {
      //command implementation
  }

  public void RaiseCanExecuteChanged()
  {
      var handler = CanExecuteChanged;
      if(handler != null)
      {
          handler(this, EventArgs.Empty);
      }
  }
}

And the view model:

public class PersonViewModel : ViewModelBase
{
  private PersonModel _PersonModel;
  private EditPersonCommand _EditPersonCommand;

  ///<remarks>
  /// must use the parameterless constructor to satisfy <Window.Resources>
  ///</remarks>
  public PersonViewModel()
     : this(new PersonModel())
  {
      _EditPersonCommand = new EditPersonCommand();
  }

  public PersonViewModel(PersonModel personModel)
  {
     _PersonModel = personModel;
  }

  public ICommand EditPersonCommand
  {
     get
     {
         return _EditPersonCommand;
     }
  }

  public PersonModel PersonModelProp
  {
      get
      {
         return _PersonModel;
      }
      set
      {
         _PersonModel = value;
         OnPropertyChanged("PersonModelProp");
         EditPersonCommand.RaiseCanExecuteChanged();
      }
    }
}

Two points to the answer:

First, as @akton mentioned, you can only bind to public properties. It doesn't have to be a DependencyProperty though.

Second, which took me some tome to figure out, is that you have to set the binding for the CommandParameter before the Command property. i.e.

<Button Content="Edit" HorizontalAlignment="Right" Height="20"  Width="80"
        CommandParameter="{Binding PersonModelProp}"
        Command="{Binding EditPersonCommand}" />

Hope this helps :)

_PersonModel is private and so cannot be accessed. Create a public property that exposes it and bind to that in the CommandParameter. Remember to make the property a dependency property (technically not required but it helps) and the ViewModel should implement INotifyProperty changed and fire the PropertyChanged event so the binding is updated.

I think you have a problem in your EditPersonCommand (it not fired ok).I check it with relayCommand and it work!

This is the code:

ViewModel:

 public class PersonViewModel : ViewModelBase
    {
        private PersonModel _PersonModel;
        private ICommand _EditPersonCommand;

        ///<remarks>
        /// must use the parameterless constructor to satisfy <Window.Resources>
        ///</remarks>
        public PersonViewModel()
            : this(new PersonModel())
        {

        }

        public PersonViewModel(PersonModel personModel)
        {
            PersonModelProp = personModel;
        }

        public ICommand EditPersonCommand
        {
            get
            {
                if (_EditPersonCommand == null)
                {
                    _EditPersonCommand = new RelayCommand(ExecuteEditPerson,CanExecuteEditPerson);
                }
                return _EditPersonCommand;
            }
        }


        private bool CanExecuteEditPerson(object parameter)
        {
            PersonModel p = parameter as PersonModel;

            return (p != null) && (p.Age > 0);
        }


        private void ExecuteEditPerson(object o)
        {

        }


        public PersonModel PersonModelProp
        {
            get
            {
                return _PersonModel;
            }
            set
            {
                _PersonModel = value;
                NotifyPropertyChanged("PersonModelProp");
            }
        }


    }

And this RelayCommand (Fire events ok!)

      public class RelayCommand : ICommand
        {
            #region Constants and Fields


            private readonly Predicate<object> canExecute;


            private readonly Action<object> execute;

            #endregion

            #region Constructors and Destructors


            public RelayCommand(Action<object> execute)
                : this(execute, null)
            {
            }

            public RelayCommand(Action<object> execute, Predicate<object> canExecute)
            {
                if (execute == null)
                {
                    throw new ArgumentNullException("execute");
                }

                this.execute = execute;
                this.canExecute = canExecute;
            }

            #endregion

            #region Events


            public event EventHandler CanExecuteChanged
            {
                add
                {
                    CommandManager.RequerySuggested += value;
                }

                remove
                {
                    CommandManager.RequerySuggested -= value;
                }
            }

            #endregion

            #region Implemented Interfaces

            #region ICommand


            [DebuggerStepThrough]
            public bool CanExecute(object parameter)
            {
                return this.canExecute == null || this.canExecute(parameter);
            }

            public void Execute(object parameter)
            {
                this.execute(parameter);
            }

            #endregion

            #endregion
        }

Xmal:

<Button Content="Edit" HorizontalAlignment="Right" Height="20"  Width="80"
 CommandParameter="{Binding PersonModelProp}" 
 Command="{Binding EditPersonCommand}" />
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!