1

The code below is MVVM class for my WPF application. In my MainWindow.xaml.cs file, MainWindow() constructor, I have done like this.

oneWayAuth = new OneWayAuthentication(); DataContext = oneWayAuth 

My Mainwindow contains multiple buttons and I need to assign events by binding like this using ICommand,

MainWindow.xaml

<Grid> <Button> Command="{Binding ClickCommand}" Content="Button" Grid.Row="1" Name="button1" /> </Grid> 

Inside event for button, I should be able to access oneWayAuth.RandomNumber property, so that I can change it.

I tried to use the method below. But I could not pass Action delegate with return type.

OneWayAuthentication.cs

public class OneWayAuthentication : INotifyPropertyChanged { private string certData; private string isVerifiedCert; private string randomNumber; private string response; private string isVerifiedRes; private string resultAuth; public string RandomNumber { get { return randomNumber; } set { randomNumber = value; NotifyPropertyChanged("RandomNumber"); } } public ICommand ClickCommand { get { ICommand intfaceCmnd = new CommandHandler(() => Execute(), () => Switch()); return intfaceCmnd; } } #region INotifyPropertyChanged Members public event PropertyChangedEventHandler PropertyChanged; #endregion #region Private Helpers private void NotifyPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } #endregion public bool Switch() { return true; } public void Execute() { this.RandomNumber = "this is random number"; } } 

CommandHandler.cs

public delegate bool delCanExecute(object parameter); public class CommandHandler:ICommand { private Action _action; private Action _canExecute; public CommandHandler(Action action1, Action action2) { _action = action1; _canExecute = action2; } public bool CanExecute(object parameter) { bool res = _canExecute(); return res; } public void Execute(object parameter) { _action(); } public event EventHandler CanExecuteChanged; } 
4
  • What happens does it not compile? Try ICommand intfaceCmnd = new CommandHandler(Execute, Switch);. Also each time your getter is called a new command instance is created, I would suggest to do create in constructor and change is only when necessary. Commented Jul 26, 2013 at 3:17
  • In line bool = _canExecute(); Cannot implicitly conver type 'void' to 'bool', in CommandHandler.cs Commented Jul 26, 2013 at 3:22
  • Its because your predicate is action and it cannot return anything. CommandHandler(Action action1, Action action2). action2 is assigned to CanExecute. Use Predicate type instead, msdn.microsoft.com/en-us/library/bfcke1bz.aspx Commented Jul 26, 2013 at 3:25
  • I would also suggest to use MVVM framework like MVVMLight where all these functionality is already implemented. Commented Jul 26, 2013 at 3:26

2 Answers 2

2

A typical command handler (RelayCommand) from MVVM light

class RelayCommand : ICommand { readonly Action<object> _execute; readonly Predicate<object> _canExecute; /// <summary> /// Initializes a new instance of the <see cref="RelayCommand"/> class. /// </summary> /// <param name="execute">The method to be called when the command is /// invoked.</param> public RelayCommand(Action<object> execute) : this(execute, null) { } /// <summary> /// Initializes a new instance of the <see cref="RelayCommand"/> class. /// </summary> /// <param name="execute">The method to be called when the command is /// invoked.</param> /// <param name="canExecute">the method that determines whether the command /// can execute in its current state.</param> public RelayCommand(Action<object> execute, Predicate<object> canExecute) { if (execute == null) throw new ArgumentNullException("execute"); _execute = execute; _canExecute = canExecute; } /// <summary> /// Defines the method that determines whether the command can execute in /// its current state. /// </summary> /// <param name="parameter">Data used by the command. If the command does /// not require data to be passed, this object can be set to null.</param> /// <returns> /// true if this command can be executed; otherwise, false. /// </returns> [DebuggerStepThrough] public bool CanExecute(object parameter) { return _canExecute == null ? true : _canExecute(parameter); } /// <summary> /// Occurs when changes occur that affect whether or not the command should /// execute. /// </summary> public event EventHandler CanExecuteChanged { add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; } } /// <summary> /// Defines the method to be called when the command is invoked. /// </summary> /// <param name="parameter">Data used by the command. If the command does /// not require data to be passed, this object can be set to null.</param> public void Execute(object parameter) { _execute(parameter); } } 

Action with object means you can pass parameter to your command and same for Predicate but it returns bool.

Sign up to request clarification or add additional context in comments.

1 Comment

how to pass Predicate in constructor? new CommandHandler(...)
1
Instead Of Action use Func<bool> public class CommandHandler:ICommand { private Action _action; private Func<bool>_canExecute; public CommandHandler(Action action1, Func<bool>action2) { _action = action1; _canExecute = action2; } 

UPDATE:

 public ICommand ClickCommand { get { ICommand intfaceCmnd = new CommandHandler(() => Execute(), () => Switch()); return intfaceCmnd; } } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.