Skip to main content Skip to footer

How to Create CommandBinding in a WPF Datagrid

When you develop WPF applications following the MVVM design pattern, you will eventually encounter the requirement to bind commands. With MVVM, you typically do not write any code behind the XAML page, such as click events, so commands are used to connect UI buttons to our ViewModel logic.

Buttons can be easily bound to a ViewModel command (see our previous blog, Using MVVM to Remove Rows from a WPF Datagrid). But what do you do when you need code-behind logic for something other than a standard button click?

How to Bind Commands to an Event

There are many instances where you need to perform some logic during an arbitrary event raise, such as the mouse-over event or clicking something other than a button. Microsoft has included the interactivity library to keep your code clean and MVVM-friendly. Through the interactivity library (System.Windows.Interactivity), we can bind any arbitrary events to our view model, thus enabling more UI controls to be MVVM-friendly.

In this blog, we'll discuss how to implement command binding in ComponentOne FlexGrid for WPF using the interactivity library when the user clicks anywhere on a row. This will allow us to do some custom business logic in the ViewModel for clicking anywhere on a row.

Ready to Start Creating? Download ComponentOne Today!

Creating the MVVM Project

First, let's create a very simple MVVM project skeleton. Create a new WPF project, "CommandBinding", and add three folders - View, Model, and ViewModel. Then, add a new class called “Employee” under the "Model" folder. This is our domain entity and contains a few properties.

namespace CommandBinding.Model
{
    class Employee
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }
    }
}

Add a class for ICommand Implementation called “DelegateCommand", to the folder "ViewModel".

namespace CommandBinding.ViewModel
{
    class DelegateCommand : ICommand
    {
        private Action m_action;
        public DelegateCommand(Action action)
        {
            this.m_action = action;
        }
        public bool CanExecute(object parameter)
        {
            return true;
        }
        public void Execute(object parameter)
        {
            m_action();
        }
        public event EventHandler CanExecuteChanged;
        public void OnCanExecuteChanged()
        {
            CanExecuteChanged(this, EventArgs.Empty);
        }
    }
}

Add another class, "EmployeeListView", to the folder "ViewModel". This View Model is responsible for sending data to and handling commands that get triggered in the View.

namespace CommandBinding.ViewModel
{
    class EmployeeListView
    {
        private ICommand m_RowClickCommand;
        public EmployeeListView()
        {
            m_RowClickCommand = new DelegateCommand(() =>
            {
                var set = this.SelectedData;
                if (set != null)
                {
                    MessageBox.Show(set.FirstName, "First Name");
                }
            });
        }
        public Employee SelectedData { get; set; }
        public ICommand RowClickCommand
        {
            get
            {
                return m_RowClickCommand;
            }
        }
        public IList<Employee> EmployeeList
        {
            get
            {
                List<Employee> _list = new List<Employee>();
                _list.Add(new Employee() { FirstName = "John", LastName = "Wayne", Age = 35 });
                _list.Add(new Employee() { FirstName = "Maximus", LastName = "Decimus", Age = 33 });
                _list.Add(new Employee() { FirstName = "Alexander", LastName = "Conklin", Age = 42 });
                _list.Add(new Employee() { FirstName = "Jason", LastName = "Bourne", Age = 66 });
                return _list;
            }
        }
    }
}

Add FlexGrid with Command Binding

Next, add a reference to your project for C1.WPF.FlexGrid and System.Windows.Interactivity. You can browse and add these from nuget.org.

Lastly, drag MainWindow.xaml to the "View" folder. Open App.xaml and change the "StartupUri" tag from "MainWindow.xaml" to "View/MainWindow.xaml".

Look at the XAML markup below for MainWindow.xaml, where we place C1FlexGrid and set command bindings for the "MouseLeftButtonUp" event trigger using Interactivity.

<!--xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:c1="http://schemas.componentone.com/winfx/2006/xaml"-->


<Grid>
    <Grid.DataContext>
        <ViewModel:EmployeeListView />
    </Grid.DataContext>
    <c1:C1FlexGrid ItemsSource="{Binding EmployeeList}"
                SelectedItem="{Binding SelectedData, Mode=TwoWay}">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="MouseLeftButtonUp">
                <i:InvokeCommandAction 
                        Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=c1:C1FlexGrid}, 
                        Path=DataContext.RowClickCommand}" />
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </c1:C1FlexGrid>
</Grid>

And this is it! Now, when you click on any row, the row gets selected with a message box that displays the value of a field from the selected DataItem. Normally, this type of action would be performed using a code behind the click event. But to make your app the most MVVM-friendly, we can avoid unmanaged code behind it thanks to the Microsoft Interactivity library.

Download C# Sample

How to Create CommandBinding in a WPF Datagrid

Ready to Start Creating? Download ComponentOne Today!

comments powered by Disqus