Search code examples
c#wpfmvvmwpf-controlswpfdatagrid

Binding Events to Commands without Blend SDK or third party. (WPF / MVVM)


Is there a way to bind Events to command without System.Windows.Interactivity or any other third party library?

So far I have tried the following:

<Style TargetType="DataGridRow">
      <EventSetter Event="MouseDoubleClick"
      Handler="{Binding DoubleClickCommand}" />
</Style>

And

<DataGrid.InputBindings>
      <MouseBinding Gesture="LeftDoubleClick" Command="{Binding DoubleClickCommand}"/>
</DataGrid.InputBindings>

And

<DataGrid ItemsSource="{Binding Model.SpectrumCollections}"
          ColumnWidth="*"
          AutoGenerateColumns="false"
          IsReadOnly="True" 
          BorderThickness="0"
          HeadersVisibility="Column" MouseDoubleClick="{Binding DoubleClickCommand}">

But nothings seems to work, any help will be much appreciated.

Edit 1: This is my implementation of the RelayCommand I use, maybe the problem is there..

public class RelayCommand : ICommand
{
    private readonly Func<bool> _canExecute;

    private readonly Action _execute;

    public RelayCommand(Action inExecute, Func<bool> inCanExecute = null)
    {
        _execute = inExecute ?? throw new Helper.Exceptions.DelegateCommandException(
                       Exceptions.InExecuteIsNullException);
        _canExecute = inCanExecute;
    }

    public event EventHandler CanExecuteChanged
    {
        add => CommandManager.RequerySuggested += value;
        remove => CommandManager.RequerySuggested -= value;
    }

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

    public void Execute(object inObject) => _execute?.Invoke();
}

Solution

  • You cannot do the following because MouseDoubleClick is en event and not a dependency property:

    MouseDoubleClick="{Binding DoubleClickCommand}">
    

    You can bind to the Command property of a MouseBinding though:

    <DataGrid.InputBindings>
        <MouseBinding Gesture="LeftDoubleClick" Command="{Binding DoubleClickCommand}"/>
    </DataGrid.InputBindings>
    

    If you want to invoke the command when you double-click on a cell, you should add the MouseBinding to the DataGridCell:

    <DataGrid x:Name="dg" AutoGenerateColumns="False">
        <DataGrid.CellStyle>
            <Style TargetType="DataGridCell">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type DataGridCell}">
                            <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
                                <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
                                    <ContentPresenter.InputBindings>
                                        <MouseBinding Gesture="LeftDoubleClick"
                                                      Command="{Binding DataContext.DoubleClickCommand,RelativeSource={RelativeSource AncestorType=DataGrid}}"/>
                                    </ContentPresenter.InputBindings>
                                </ContentPresenter>
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </DataGrid.CellStyle>
        <DataGrid.InputBindings>
            <MouseBinding Gesture="LeftDoubleClick" Command="{Binding DoubleClickCommand}"/>
        </DataGrid.InputBindings>
        <DataGrid.Columns>
            <DataGridTextColumn Header="Name" Binding="{Binding Name}" />
        </DataGrid.Columns>
    </DataGrid>