diff --git a/Commands/RelayCommand.cs b/Commands/RelayCommand.cs new file mode 100644 index 0000000..816c993 --- /dev/null +++ b/Commands/RelayCommand.cs @@ -0,0 +1,62 @@ +using System; +using System.Windows.Input; + +namespace MVVM_DEMO.Commands +{ + /// + /// A command whose sole purpose is to relay its functionality to other objects by invoking delegates. + /// The default return value for the CanExecute method is 'true'. + /// + public class RelayCommand : ICommand + { + private readonly Action _execute; + private readonly Func? _canExecute; + + /// + /// Occurs when changes occur that affect whether or not the command should execute. + /// + public event EventHandler? CanExecuteChanged + { + add { CommandManager.RequerySuggested += value; } + remove { CommandManager.RequerySuggested -= value; } + } + + /// + /// Creates a new command that can always execute. + /// + /// The execution logic. + public RelayCommand(Action execute) : this(execute, null) + { + } + + /// + /// Creates a new command. + /// + /// The execution logic. + /// The execution status logic. + public RelayCommand(Action execute, Func? canExecute) + { + _execute = execute ?? throw new ArgumentNullException(nameof(execute)); + _canExecute = canExecute; + } + + /// + /// Determines whether this command can execute in its current state. + /// + /// Data used by the command. If the command does not require data to be passed, this object can be set to null. + /// true if this command can be executed; otherwise, false. + public bool CanExecute(object? parameter) + { + return _canExecute == null || _canExecute(parameter); + } + + /// + /// Executes the command. + /// + /// Data used by the command. If the command does not require data to be passed, this object can be set to null. + public void Execute(object? parameter) + { + _execute(parameter); + } + } +} diff --git a/ViewModels/MainViewModel.cs b/ViewModels/MainViewModel.cs index 6499a0b..d2dafc4 100644 --- a/ViewModels/MainViewModel.cs +++ b/ViewModels/MainViewModel.cs @@ -5,6 +5,8 @@ using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Windows.Input; +using MVVM_DEMO.Commands; using MVVM_DEMO.Models; namespace MVVM_DEMO.ViewModels @@ -28,6 +30,9 @@ namespace MVVM_DEMO.ViewModels { _products = new ObservableCollection(); LoadData(); + + // Initialize commands + AddProductCommand = new RelayCommand(ExecuteAddProduct, CanExecuteAddProduct); } // read data @@ -46,5 +51,28 @@ namespace MVVM_DEMO.ViewModels public string productName { get; set; } public int productPrice { get; set; } + // Commands + public ICommand AddProductCommand { get; set; } + + // Command methods + private void ExecuteAddProduct(object? parameter) + { + Random random = new Random(); + int randomPrice = random.Next(10, 100); + + Products.Add(new Product + { + ProductName = $"Product {Products.Count + 1}", + Price = randomPrice + }); + } + + private bool CanExecuteAddProduct(object? parameter) + { + // You can add validation logic here + // For now, always allow adding products + return true; + } + } } diff --git a/Views/MainWindow.xaml b/Views/MainWindow.xaml index 21f4ec2..81cfe7a 100644 --- a/Views/MainWindow.xaml +++ b/Views/MainWindow.xaml @@ -26,7 +26,7 @@ Content="Add Product" Width="100px" Height="25px" - Click="btnAddProduct_Click" /> + Command="{Binding AddProductCommand}" />