locked
ICommand and MVVM

    Question

  • I have a class that implements ICommand and I'm exposing it as a property on my ViewModel. In my xaml I have the following:

     

    <Button Content="{Binding LoadCommand}" Command="{Binding LoadCommand}"/>

     

    At runtime I see there is content set on the button (my custom command ToString()). However, clicking the button doesn't do anything. Digging further, I see that the ButtonBase.Command property is null. In other words, it doesn't seem like the binding is working.

     

    Is there any reason this would be happening? Also, is there any way to debug bindings in this tools preview?

    Saturday, September 17, 2011 10:08 PM

Answers

  • The following works - XAML:
        <Button Content="{Binding Title}" Command="{Binding DoItCommand}"/>
    
    

    ViewModel:
      public class ViewModel : INotifyPropertyChanged
      {
        public ICommand DoItCommand { get; set; }
        private string  _title="Title";
    
          // Setup command
        public ViewModel()
        {
          DoItCommand = new DelegateCommand(DoIt);
        }
    
        public string Title
        {
          get { return _title; }
          set
          {
            _title = value;
            if (null != PropertyChanged)
            {
              PropertyChanged(this, new PropertyChangedEventArgs("Title"));
            }
          }
        }
    
        private void DoIt(object param)
        {
          Title = "DoIt";
        }
    
        public event PropertyChangedEventHandler PropertyChanged = null;
      }
    
    ICommand:
      public class DelegateCommand : ICommand
      {
        Action<object>        executeAction;
    
        public DelegateCommand(Action<object> executeAction)
        {
          this.executeAction = executeAction;
        }
    
        public bool CanExecute(object parameter)
        {
          return true;
        }
    
        public void Execute(object parameter)
        {
          executeAction(parameter);
        }
    
        public event Windows.UI.Xaml.EventHandler CanExecuteChanged = null;
      }
    

    Joe 
    Sunday, September 18, 2011 12:46 AM

All replies

  • The following works - XAML:
        <Button Content="{Binding Title}" Command="{Binding DoItCommand}"/>
    
    

    ViewModel:
      public class ViewModel : INotifyPropertyChanged
      {
        public ICommand DoItCommand { get; set; }
        private string  _title="Title";
    
          // Setup command
        public ViewModel()
        {
          DoItCommand = new DelegateCommand(DoIt);
        }
    
        public string Title
        {
          get { return _title; }
          set
          {
            _title = value;
            if (null != PropertyChanged)
            {
              PropertyChanged(this, new PropertyChangedEventArgs("Title"));
            }
          }
        }
    
        private void DoIt(object param)
        {
          Title = "DoIt";
        }
    
        public event PropertyChangedEventHandler PropertyChanged = null;
      }
    
    ICommand:
      public class DelegateCommand : ICommand
      {
        Action<object>        executeAction;
    
        public DelegateCommand(Action<object> executeAction)
        {
          this.executeAction = executeAction;
        }
    
        public bool CanExecute(object parameter)
        {
          return true;
        }
    
        public void Execute(object parameter)
        {
          executeAction(parameter);
        }
    
        public event Windows.UI.Xaml.EventHandler CanExecuteChanged = null;
      }
    

    Joe 
    Sunday, September 18, 2011 12:46 AM
  • Note: I tried the above, and it works as is, but then when the consumer of the DelegateCommand provides a real implementation of CanExecute (and the code above is modified to actually store and call out on that Func<>), the Button using this ICommand is not disabled when CanExecute returns false.

    The CanExecute method is not called when CanExecute returns false, it's just that the UI element (Button) does not disable itself.

     

    Friday, September 23, 2011 9:15 PM
  • Are you raising the CanExecuteChanged event? Joe's code doesn't do anything with that event and it doesn't need to because CanExecute is hard-coded to true. But if you want to change what CanExecute returns over time, you also need to raise change notifications.
    Wednesday, September 28, 2011 3:54 PM
  • Has anything changed for the Consumer Preview version? When I try to bind a DelegateCommand, its functions are never called.
    The weird thing is that it works without the binding. ie, I can connect an instance of the same DelegateCommand class using code behine and it works perfectly.

    I know for a fact that the binding returns the command - I double checked using a debug converter.

    Any ideas?

    Wednesday, April 4, 2012 9:19 AM