简体   繁体   中英

How to prevent datagridview from firing UserDeletingRow-event for every selected row?

How can i stop the DataGridView control from triggering the UserDeletingRow -event for every selected row after i've already consumed the first?

This grid is bound to objects from my wcf-webservice, i want to execute the delete method only once with all objects that should be deleted.

This event handler is triggered for every selected row which also triggers always "do you really want to delete"-messageboxes:

private void Grid_UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e)
{
    switch (this.Type)
    {
        case AdminType.Channel:
            List<Channel> channels = GrdChannel.SelectedRows.Cast<DataGridViewRow>()
              .Select(row => (Channel)row.DataBoundItem).ToList();
            e.Cancel = !Delete_Channels(channels);
            break;
        // other types ...
        default:
            break;
    }
}

This method calls the webservice after confirmation:

private bool Delete_Channels(List<Channel> channels)
{
    var msg = string.Format("Do you really want to delete {0}?", channels.Count == 1 ? "this channel" : "these channels");
    var title = channels.Count == 1 ? "Delete channel" : "Delete channels";
    bool yes = MessageBox.Show(msg, title, MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.Yes;
    if (yes)
    {
        using (var db = new ERP_ServiceClient())
            db.DeleteChannels(channels, this.IdUser);
        string message = string.Format("{0} deleted successfully: {1}"
                                      , channels.Count == 1 ? "Channel" : "Channels"
                                      , string.Join(",", channels.Select(p => p.Name)));
        channelBindingSource.Remove(channels);
        Main.ShowStatusMessage(message);
    }
    return yes;
}

Ok, apparently there is no better approach(in terms of readability) so i've implemented Tigrans suggestion to use a count variable in the event handler and start deleting only after the last selected row triggered this event.

Here's the workaround:

private int _deleteCount = 0;
private bool _deleting = false;
private bool _reallyDelete = false;
private IEnumerable<object> _deleteEntities = null;

private void Grid_UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e)
{
    DataGridView grid = (DataGridView)sender;

    if (!_deleting)
    {
        _deleting = true;
        _deleteCount = grid.SelectedRows.Count;
        _deleteEntities = grid.SelectedRows.Cast<DataGridViewRow>().Select(r => r.DataBoundItem).ToList();
        string msg = "";
        string title = "";

        switch (this.Type)
        {
            case AdminType.Channel:
                msg = string.Format("Do you really want to delete {0}?", _deleteCount == 1 ? "this channel" : "these channels");
                title = _deleteCount == 1 ? "Delete channel" : "Delete channels";
                break;
            // other types ...
            default:
                break;
        }
        _reallyDelete = MessageBox.Show(msg, title, MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.Yes;
    }

    e.Cancel = !_reallyDelete;

    // wait until all events are triggered before starting to delete
    if (--_deleteCount == 0)
    {
        switch (this.Type)
        {
            case AdminType.Channel:
                List<Channel> channels = _deleteEntities.Cast<Channel>().ToList();
                Delete_Channels(channels);
                break;
            // other types ...
            default:
                break;
        }
        _deleting = false;
        _reallyDelete = false;
        _deleteEntities = null;
    }
}

rplace event of UserDeletingRow with this event key_Down

if ( e.KeyValue == 46 ) // Delete Key

{ e.Handled = MessageBox.Show( "Do you want really to delete the selected rows", "Confirm", MessageBoxButtons.OKCancel, MessageBoxIcon.Question ) != DialogResult.OK; }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM