S
S
SitrixEug2017-05-26 07:44:47
WPF
SitrixEug, 2017-05-26 07:44:47

How to correctly supplement the Application.Delete command, preserving its basic execution?

There is a base ViewModel in which I want to override the Application.Delete command by adding something like the "Delete entry" request?, and if the response is positive, call the standard command handler.
Of course, you can process the event in the datagrid, like this:

private void DG_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Delete)
            {
                if (MessageBox.Show(Putl.Properties.Resources.Messages_Delete, "", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
                {
                    DG.CanUserDeleteRows = true;
                }
                else
                {
                    DG.CanUserDeleteRows = false;
                }
            }
        }

But firstly, there are a bunch of such datagrids in a bunch of windows, I don’t want to fence copy-paste, and secondly, according to MVVM, it’s not customary to make event handlers.
So far, I have not been able to find how to call its basic execution inside the Delete command handler. Maybe someone knows?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
S
SitrixEug, 2017-05-29
@SitrixEug

At the moment, I found a solution - to create my own separate command that will make a request for deletion, and if confirmed, call Application.Delete
Like this:

public static class GridCommands
{
  public static readonly  RoutedUICommand Delete = 
    new RoutedUICommand(
      "Удалить строку",
      "DeleteRow",
      typeof (GridCommands),
      new InputGestureCollection(new[] {new KeyGesture(Key.Delete)})
    );
}

public class DeleteBinding : CommandBinding
{
  public DeleteBinding()
  {
    Command = GridCommands.Delete;
    CanExecute += DeleteBindingCanExecute;
    Executed += DeleteBindingExecuted;
  }

  static void DeleteBindingExecuted(object sender, ExecutedRoutedEventArgs e)
  {
    if (MessageBox.Show("Delete this?", "Delete this?", MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes)
      return;
    ApplicationCommands.Delete.Execute(e.Parameter, (IInputElement)sender);
  }

  static void DeleteBindingCanExecute(object sender, CanExecuteRoutedEventArgs e)
  {
    e.CanExecute = ApplicationCommands.Delete.CanExecute(e.Parameter, (IInputElement)sender);
  }
}

<Grid>
  <Grid.RowDefinitions>
    <RowDefinition />
    <RowDefinition />
  </Grid.RowDefinitions>
  <DataGrid
    Name="ItemsGrid"
    ItemsSource="{Binding Items}">
    <DataGrid.Columns>
      <DataGridTextColumn
        Binding="{Binding}"
        Header="N"
        Width="*"
        IsReadOnly="True"/>
    </DataGrid.Columns>
    <DataGrid.CommandBindings>
      <l:DeleteBinding />
    </DataGrid.CommandBindings>
  </DataGrid>
  <Button
    Grid.Row="1"
    Padding="5"
    VerticalAlignment="Center"
    HorizontalAlignment="Center"
    Content="Delete Row"
    Command="{x:Static l:GridCommands.Delete}"
    CommandTarget="{Binding ElementName=ItemsGrid}" />
</Grid>

There is also an option to inherit from DataGrid, and make row deletion handlers there

S
Sumor, 2017-05-27
@Sumor

To assign handlers to a command, you need to specify in the CommangBindings section of the control in which this command will be called or in any of its logical ancestors, the Execute event handler and/or the CanExecute handler.
After that, you bind the command to a menu item, button, through the corresponding Command property, or specify a hot key or mouse gesture through InputBindings.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question