Deleting Rows

Sep 22, 2008 at 2:51 PM
Hi,

I'm investigating the datagrid to see if we can use it in an existing product in place of another 3rd party grid.  What I can't see is how I catch the deletion of a row.  I see events for Begin_Edit etc but no Deleting/Deleted events that I can catch to do some important updating before/after the object is deleted.

Am I missing something?

Thanks

John
Coordinator
Sep 22, 2008 at 6:16 PM
DataGrid.DeleteCommand will be executed when the user chooses to delete a row. You can prevent it from occurring by handling the CommandManager.CanExecute event, checking that the command is DeleteCommand, and setting the CanExecute property on the event arguments to false. To just be notified, then you would need to hookup an CommandManager.Executed event handler and check that the command is DeleteCommand. It is important not to mark this event as handled or the DataGrid will not receive the event.

This could benefit from a Deleting/Deleted event pair to simplify what you want to do. I will suggest this to the team.

Ben
Sep 23, 2008 at 9:13 AM
Glad I'm not going mad - couldn't find the events and thought I was just not seeing them.  I'll try out the command manager idea as we already handle commands in the app and see where I get to. 

What about new row(s)?  It would be nice if... there were events for: AddingNewRow/AddedNewRow as well.  Then it is easier to distinguish between editing an existing row and creating a new one.

I found the BeginEdit/CancelEdit/CommitEdit events which are good for when you are editing existing rows.


John
Coordinator
Sep 23, 2008 at 6:09 PM
Yes, if delete events were added, then events for AddNewRow would also be added as well.

At present, you can also listen for the InitializingNewItem event, which is called when a new item is created and allows you to set properties on the new item to values other than the object's default values.

Ben
Sep 24, 2008 at 4:05 AM
Hi,

I am trying to get notification when a row is being deleted and I am having trouble using the CommandManager.Executed event handler.  Do you mind posting some code as to has this can be achieved?  Also, I am trying to provide some custom bindings and one of them was to use the delete key for my own purpose but it never get fired?  Please advise.

Thanks,

Matt
Coordinator
Sep 25, 2008 at 2:33 AM
Here is an example of attaching to the CommandManager.CanExecuteEvent and disabling the DeleteCommand under some condition.  The condition in this example is trivial and only to show that the DeleteCommand can be disabled under a condition that I define.

_handler = new CanExecuteRoutedEventHandler(OnCanExecuteRoutedEventHandler);
EventManager.RegisterClassHandler(typeof(DataGrid), CommandManager.CanExecuteEvent, _handler);

void

 

OnCanExecuteRoutedEventHandler(object sender, CanExecuteRoutedEventArgs e)
{
    RoutedCommand routedCommand = (e.Command as RoutedCommand);
    if (routedCommand != null)
    {
        if (routedCommand.Name == "Delete")
        {
            e.CanExecute = DataGrid_Standard.CanUserResizeColumns;
            if(!e.CanExecute)
            e.Handled =
true;
        }
    }
}

 

Oct 23, 2008 at 5:18 AM
Hi,

How can I unregistered the delete command handler (shown in above blog)?

I am using this concept to validate and display some message before deleting the row. So, when first time I press delete it calls the handler (where command = "Delete") only one time. But when close that page and open the that page again without closing whole application, it call the delete handler (with command="Delete") twice.... and so on...

So, I played around to find a way to unregistered this handler but I failed.

Can anybody help me in this?

Thanks.
Coordinator
Oct 24, 2008 at 8:43 PM

You cannot unregister from class handlers. Use instance handlers instead.

element.AddHandler(CommandManager.CanExecuteEvent, handler);

element.RemoveHandler(CommandManager.CanExecuteEvent, handler);

Ben

Oct 27, 2008 at 1:48 AM
Hi Ben,

Thanks for your reply. I did try the way you suggest me (adding and removing the handler). But, its not working for me. My code snippet is like...

1  myClass{

3  private CanExecuteRoutedEventHandler DeleteHandler;

5  myClass(){

6              DeleteHandler = OnCanExecuteRoutedEventHandler;

7              //EventManager.RegisterClassHandler(typeof(Microsoft.Windows.Controls.DataGrid), CommandManager.CanExecuteEvent, DeleteHandler );
                    }

myClassLoaded{

                             myDataGrid.AddHandler(CommandManager.CanExecuteEvent, DeleteHandler);
                         }

myClassUnLoaded{

                           myDataGrid.RemoveHandler(CommandManager.CanExecuteEvent, DeleteHandler);
                              }


private static void OnCanExecuteRoutedEventHandler(object sender, CanExecuteRoutedEventArgs e)
        {
            RoutedCommand routedCommand = (e.Command as RoutedCommand);
            if (routedCommand != null)
            {
                if (routedCommand.Name == "Delete")
                {
                    MessageBoxResult result = MessageBox.Show("Are you sure, you want to delete?", "Delete Items", MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.Yes);
                    if (result == MessageBoxResult.No)
                    {
                        e.CanExecute = false;
                        e.Handled = true;
                        return;
                    }
                    //e.CanExecute = false;
                    //if (!e.CanExecute)
                    //    e.Handled = true;
                }
            }
        }


}


Its not event calling the handler. Than I did try registering the class (uncommenting line 7) but than the same problem as before. May be I am doing something wrong as I am new to MicroSoft and Wpf stuff.

Any help?

Thanks.
Oct 27, 2008 at 5:36 AM
Edited Oct 27, 2008 at 6:10 AM
Hi Ben, Its working now. I found the problem that I need to add handler in contructor rather than pageLoad event and may be I need to put true as third argument.

myDataGrid.AddHandler(CommandManager.CanExecuteEvent, new CanExecuteRoutedEventHandler(DeleteHandler), true);

and I don't need remove handler (I don't know why?).

Now, but the problem is that, even if I select the single cell and not the row, it calls the handler. any idea why?

Thanks.
Coordinator
Oct 27, 2008 at 5:21 PM
CanExecute is used to determine whether a command is enabled or not. However, you are confusing that with whether the end-user wishes a command that has been executed to complete. You should handle the move the code you currently have for CanExecute to an Executed event handler instead. You also might consider subclassing DataGrid and overriding OnExecutedBeginEdit instead.

Ben
Feb 27, 2009 at 3:56 PM
Just a side note for anyone trying this:

If you use an instance handler for the Delete Command via element.AddHandler() you need to use the overload to signal that you want handledEventsToo, otherwise your handler will not fire for the Delete Command because it will be handled already and will not continue routing.