Implementeer ICommand patroon met RelayCommand voor MVVM
- Voeg RelayCommand class toe voor herbruikbare ICommand implementatie - Vervang button click event handler door AddProductCommand in MainViewModel - Update XAML om Command binding te gebruiken in plaats van Click event - Verwijder business logic uit code-behind (MainWindow.xaml.cs) - Los DataContext duplicatie op (was twee keer MainViewModel instantie) Dit maakt de applicatie beter testbaar en volgt proper MVVM principes. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
62
Commands/RelayCommand.cs
Normal file
62
Commands/RelayCommand.cs
Normal file
@@ -0,0 +1,62 @@
|
||||
using System;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace MVVM_DEMO.Commands
|
||||
{
|
||||
/// <summary>
|
||||
/// 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'.
|
||||
/// </summary>
|
||||
public class RelayCommand : ICommand
|
||||
{
|
||||
private readonly Action<object?> _execute;
|
||||
private readonly Func<object?, bool>? _canExecute;
|
||||
|
||||
/// <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>
|
||||
/// Creates a new command that can always execute.
|
||||
/// </summary>
|
||||
/// <param name="execute">The execution logic.</param>
|
||||
public RelayCommand(Action<object?> execute) : this(execute, null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new command.
|
||||
/// </summary>
|
||||
/// <param name="execute">The execution logic.</param>
|
||||
/// <param name="canExecute">The execution status logic.</param>
|
||||
public RelayCommand(Action<object?> execute, Func<object?, bool>? canExecute)
|
||||
{
|
||||
_execute = execute ?? throw new ArgumentNullException(nameof(execute));
|
||||
_canExecute = canExecute;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether this 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>
|
||||
public bool CanExecute(object? parameter)
|
||||
{
|
||||
return _canExecute == null || _canExecute(parameter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes the command.
|
||||
/// </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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<Product>();
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
Content="Add Product"
|
||||
Width="100px"
|
||||
Height="25px"
|
||||
Click="btnAddProduct_Click" />
|
||||
Command="{Binding AddProductCommand}" />
|
||||
<Label Content="Selected Product Details"
|
||||
FontWeight="Bold"
|
||||
FontSize="16"
|
||||
|
||||
@@ -18,12 +18,10 @@ namespace MVVM_DEMO
|
||||
/// </summary>
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
MainViewModel viewModel = new MainViewModel();
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.DataContext = viewModel;
|
||||
// ViewModel is already set in XAML via Window.DataContext
|
||||
comboBox.SelectionChanged += ComboBox_SelectionChanged;
|
||||
// initial selection
|
||||
if (comboBox.Items.Count > 0)
|
||||
@@ -35,25 +33,15 @@ namespace MVVM_DEMO
|
||||
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
// display selected product details
|
||||
if (comboBox.SelectedItem != null)
|
||||
if (comboBox.SelectedItem != null && DataContext is MainViewModel viewModel)
|
||||
{
|
||||
viewModel.productName = ((Product)comboBox.SelectedItem).ProductName;
|
||||
viewModel.productPrice = (int)((Product)comboBox.SelectedItem).Price;
|
||||
viewModel.OnPropertyChanged("productName");
|
||||
viewModel.OnPropertyChanged("productPrice");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void btnAddProduct_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// toevoegen van een product in het viewmodel
|
||||
Product p = new Product();
|
||||
p.ProductName = $"Product {viewModel.Products.Count + 1}";
|
||||
// generate a random price between 10 and 100
|
||||
Random rand = new Random();
|
||||
p.Price = rand.Next(10, 100);
|
||||
viewModel.Products.Add(p);
|
||||
}
|
||||
// btnAddProduct_Click removed - now using Command binding in XAML
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user