Lightweight Commanding in Silverlight 4: A 5-Step Walkthrough

The MVVM pattern becomes far more powerful once you wire up commands, yet Silverlight 4 does not ship with a built-in ICommand implementation. The snippet below shows a minimal, self-contained approach that avoids external toolkits.

Step 1 – Craft a reusable command object

Create a class that fulfills ICommand by forwarding calls to two delegates: one for execution and one for the optional "can-execute" guard.

public sealed class SimpleCommand : ICommand
{
    private readonly Action<object> _execute;
    private readonly Predicate<object> _canExecute;

    public SimpleCommand(Action<object> execute, Predicate<object> canExecute = null)
    {
        _execute    = execute ?? throw new ArgumentNullException(nameof(execute));
        _canExecute = canExecute;
    }

    public bool CanExecute(object parameter) => _canExecute?.Invoke(parameter) ?? true;

    public void Execute(object parameter) => _execute(parameter);

    public event EventHandler CanExecuteChanged;
    public void RaiseCanExecuteChanged() => CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}

Step 2 – Expose a command from the ViewModel

Add a public read-only property typed as ICommand. The view will bind to this member.

public ICommand RefreshCommand { get; private set; }

Step 3 – Instantiate the command

In the ViewModel constructor, hook the delegates to real methods (or lambdas).

RefreshCommand = new SimpleCommand(OnRefreshRequested, CanRefresh);

Step 4 – Make the ViewModel discoverable

Expose the ViewModel through XAML so the designer can see it. A common trick is to declare it as a resource.

<UserControl.Resources>
    <local:MainViewModel x:Key="MainVM" />
</UserControl.Resources>

Step 5 – Bind the UI element

Any control that implements ICommandSource (Button, HyperlinkButton, etc.) can now bind to the command. Use CommandParameter to pipe data from the view.

<Button Content="Refresh"
        Width="120"
        Command="{Binding RefreshCommand}"
        CommandParameter="{Binding ElementName=FilterBox, Path=Text}" />

After these five steps, the button automatically enables or disables itself and triggers the ViewModel logic without any code-behind.

Complete ViewModel sample

public class MainViewModel : INotifyPropertyChanged
{
    public MainViewModel()
    {
        AllItems = new ObservableCollection<Item>
        {
            new Item { Id = 1, Name = "Apple" },
            new Item { Id = 2, Name = "Orange" },
            new Item { Id = 3, Name = "Banana" },
            new Item { Id = 4, Name = "Pear" }
        };

        FilteredItems = new ObservableCollection<Item>();

        RefreshCommand = new SimpleCommand(Refresh, CanRefresh);
    }

    public ICommand RefreshCommand { get; }

    public ObservableCollection<Item> AllItems { get; }
    public ObservableCollection<Item> FilteredItems { get; }

    private void Refresh(object parameter)
    {
        var text = parameter as string ?? string.Empty;
        FilteredItems.Clear();

        foreach (var item in AllItems.Where(i => i.Name.StartsWith(text, StringComparison.OrdinalIgnoreCase)))
            FilteredItems.Add(item);
    }

    private bool CanRefresh(object parameter) => true;

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged([CallerMemberName] string property = null) =>
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
}
public sealed class Item
{
    public int Id { get; set; }
    public string Name { get; set; }
}

Tags: Silverlight mvvm ICommand DelegateCommand DataBinding

Posted on Fri, 12 Jun 2026 16:30:43 +0000 by tapupartforpres