In this article, we will learn about button click event in WPF with MVVM concept. We use ICommand interface for generating the button click event. Let's take one simple example of one simple textbox and button. After writing the text in textbox, when we click on button, it will display a simple message box.
Before starting this article, please read
Explain INotifyPropertyChanged In WPF - MVVM article first.
First, create one WPF application and create a window like the following.
XAML code
- <Window x:Class="MVVM_ICommand.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525">
- <StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center">
- <TextBox Width="120" Height="30" Margin="10"></TextBox>
- <Button Width="90" Margin="10" Content="Click Me"></Button>
- </StackPanel>
- </Window>
Now, we have to create one command class along with a View-Model class. View-Model contains some properties like Name. Now, let's implement the View-Model with INotifyProperyChanged interface. This implementation is given in my previous article.
Give View-Model namespace reference to the View and define the window resource file. Then, give data context to the parent control and also, bind the text property of the text box.
Now, let’s start our main code for making a new class RelayCommand. Make it as public.
- public class RelayCommand {}
-
-
- public class RelayCommand: ICommand {
- public boolCanExecute(object parameter) {
-
- }
- public event EventHandlerCanExecuteChanged;
- public void Execute(object parameter) {
-
- }
- }
It will create two methods and one event. The first method "CanExecute" decides whether we are allowed to fire the command ( the button click event) or not. The second method "Execute" method contains the actual logic. If CanExecute method returns true, then Execute method is run.
Now, Create two action properties that we initialize in constructor of the relay command class.
- Action < object > _execteMethod;
- Func < object,bool> _canexecuteMethod;
-
- public RelayCommand(Action < object > execteMethod, Func <object , bool> canexecuteMethod) {
- _execteMethod = execteMethod;
- _canexecuteMethod = canexecuteMethod;
- }
Here, in CanExecute method, we put null validation to check if _canexecutemethod is initialized or not. If not, then it returns false; otherwise it returns true. Also, write the logic for Execute method. Here, we simply initialize the _execute method because we make this RelayCommand class to be generalized.
- public boolCanExecute(object parameter) {
- if (_canexecuteMethod != null) {
- return true;
- } else {
- return false;
- }
- }
- public void Execute(object parameter) {
- _execteMethod(parameter);
- }
Now, let's define “CanExecuteChanged” the event logic, which will run the canExecute method continuously.
- public event EventHandlerCanExecuteChanged
- {
- add { CommandManager.RequerySuggested += value; }
- remove { CommandManager.RequerySuggested -= value; }
- }
Full RelayCommand class code
- public class RelayCommand: ICommand
- Action < object > _execteMethod;
- Func <object, bool> _canexecuteMethod;
-
- public RelayCommand(Action < object > execteMethod, Func <object , bool> canexecuteMethod) {
- _execteMethod = execteMethod;
- _canexecuteMethod = canexecuteMethod;
- }
-
- public boolCanExecute(object parameter) {
- if (_canexecuteMethod != null) {
- return _canexecutemethod(parameter);
- } else {
- return false;
- }
- }
-
- public event EventHandlerCanExecuteChanged {
- add {
- CommandManager.RequerySuggested += value;
- }
- remove {
- CommandManager.RequerySuggested -= value;
- }
- }
-
- public void Execute(object parameter) {
- _execteMethod(parameter);
- }
- }
Now, go for the View-Model class and create the ICommand property, as shown below.
- public ICommand MyCommand { get; set; }
And, also create two methods like,
- private bool CanExecuteMyMethod(object parameter) {
- if (string.IsNullOrEmpty(Name)) {
- return false;
- } else {
- if (Name < > "") {
- return true;
- } else {
- return false;
- }
-
- }
- }
-
- private void ExecuteMyMethod(object parameter) {
- MessageBox.Show("Hello... " + Name);
- }
Now, create constructor for View-Model and pass both these methods to it.
- public ViewModel()
- {
- MyCommand = new RelayCommand(ExecuteMyMethod,
- CanExecuteMyMethod);
- }
Full View-Model Code
- public class ViewModel {
-
- public ICommand MyCommand {
- get;
- set;
- }
-
- private string _name;
-
- public string Name {
- get {
- return _name;
- }
- set {
- _name = value;
- }
- }
-
- public ViewModel() {
- MyCommand = new RelayCommand(ExecuteMyMethod, CanExecuteMyMethod);
- }
-
-
- private boolCanExecuteMyMethod(object parameter) {
- if (string.IsNullOrEmpty(Name)) {
- return false;
- } else {
- if (Name < > "") {
- return true;
- } else {
- return false;
- }
-
- }
- }
-
- private void ExecuteMyMethod(object parameter) {
- MessageBox.Show("Hello... " + Name);
- }
-
- }
Now, go for the design View. Build the Solution and open the View's XAML code. Set the command property and give command a name.
<Button Width="90" Margin="10" Content="Click Me" Command="{Binding MyCommand}"></Button>
Full XAML Code
- <Window x:Class="MVVM_ICommand.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:viewmodel="clr-namespace:MVVM_ICommand.ViewModel" Title="MainWindow" Height="350" Width="525">
- <Window.Resources>
- <viewmodel:ViewModel x:Key="vm"></viewmodel:ViewModel>
- </Window.Resources>
- <StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center" DataContext="{Binding Source={StaticResourcevm}}">
- <TextBox Width="120" Height="30" Margin="10" Text="{Binding Path=Name , Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></TextBox>
- <Button Width="90" Margin="10" Content="Click Me" Command="{Binding MyCommand}"></Button>
- </StackPanel>
- </Window>
Run the application.
Write the text in textbox and click on button.
This will display a message, as shown below.
This is how this command interface works in MVVM . If you have any confusion, you can download the attached source code and debug it line by line.