C# 如何防止datagridview为每个选定行触发UserDeletingRow事件?

C# 如何防止datagridview为每个选定行触发UserDeletingRow事件?,c#,winforms,data-binding,datagridview,event-handling,C#,Winforms,Data Binding,Datagridview,Event Handling,在我已经使用了第一行之后,如何阻止DataGridView控件触发每个选定行的UserDeletingRow-事件 这个网格绑定到我的wcf webservice中的对象,我只想对所有应该删除的对象执行一次delete方法 此事件处理程序针对每个选定行触发,该行也始终触发“您真的要删除吗”-MessageBox: private void Grid_UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e) { swi

在我已经使用了第一行之后,如何阻止
DataGridView
控件触发每个选定行的
UserDeletingRow
-事件

这个网格绑定到我的wcf webservice中的对象,我只想对所有应该删除的对象执行一次delete方法

此事件处理程序针对每个选定行触发,该行也始终触发“您真的要删除吗”-MessageBox:

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;
    }
}
private void Grid\u UserDeletingRow(对象发送方,DataGridViewRowCancelEventArgs e)
{
开关(此.Type)
{
案例管理员类型。频道:
List channels=GrdChannel.SelectedRows.Cast()
.Select(row=>(Channel)row.DataBoundItem.ToList();
e、 取消=!删除_个频道(频道);
打破
//其他类型。。。
违约:
打破
}
}
此方法在确认后调用webservice:

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;
}
private bool Delete_频道(列出频道)
{
var msg=string.Format(“是否确实要删除{0}?”,channels.Count==1?“此频道”:“这些频道”);
var title=channels.Count==1?“删除频道”:“删除频道”;
bool yes=MessageBox.Show(msg、title、MessageBoxButtons.YesNo)==System.Windows.Forms.DialogResult.yes;
如果(是)
{
使用(var db=new ERP\u ServiceClient())
db.DeleteChannels(channels,this.IdUser);
string message=string.Format(“{0}已成功删除:{1}”
,channels.Count==1?“Channel”:“channels”
,string.Join(“,”,channels.Select(p=>p.Name));
channelBindingSource。删除(通道);
Main.ShowStatusMessage(消息);
}
返回yes;
}

好的,显然没有更好的方法(在可读性方面),所以我实施了Tigrans建议,在事件处理程序中使用count变量,并仅在最后一个选定行触发此事件后才开始删除

以下是解决方法:

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;
    }
}
private int\u deleteCount=0;
private bool\u deleting=false;
private bool\u reallyDelete=false;
私有IEnumerable _deleteEntities=null;
私有void Grid_UserDeletingRow(对象发送方,DataGridViewRowCancelEventArgs e)
{
DataGridView网格=(DataGridView)发送方;
如果(!\u删除)
{
_删除=真;
_deleteCount=grid.SelectedRows.Count;
_deleteEntities=grid.SelectedRows.Cast().Select(r=>r.DataBoundItem.ToList();
字符串msg=“”;
字符串标题=”;
开关(此.Type)
{
案例管理员类型。频道:
msg=string.Format(“是否确实要删除{0}?”,_deleteCount==1?“此频道”:“这些频道”);
title=\u deleteCount==1?“删除频道”:“删除频道”;
打破
//其他类型。。。
违约:
打破
}
_reallyDelete=MessageBox.Show(msg、title、MessageBoxButtons.YesNo)==System.Windows.Forms.DialogResult.Yes;
}
e、 取消=!\u真正删除;
//等待所有事件触发后再开始删除
如果(---\u deleteCount==0)
{
开关(此.Type)
{
案例管理员类型。频道:
列表通道=_deleteEntities.Cast().ToList();
删除_频道(频道);
打破
//其他类型。。。
违约:
打破
}
_删除=假;
_reallyDelete=false;
_deleteEntities=null;
}
}

好的,显然没有更好的方法(在可读性方面),所以我实施了Tigrans建议,在事件处理程序中使用count变量,并仅在最后一个选定行触发此事件后才开始删除

以下是解决方法:

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;
    }
}
private int\u deleteCount=0;
private bool\u deleting=false;
private bool\u reallyDelete=false;
私有IEnumerable _deleteEntities=null;
私有void Grid_UserDeletingRow(对象发送方,DataGridViewRowCancelEventArgs e)
{
DataGridView网格=(DataGridView)发送方;
如果(!\u删除)
{
_删除=真;
_deleteCount=grid.SelectedRows.Count;
_deleteEntities=grid.SelectedRows.Cast().Select(r=>r.DataBoundItem.ToList();
字符串msg=“”;
字符串标题=”;
开关(此.Type)
{
案例管理员类型。频道:
msg=string.Format(“是否确实要删除{0}?”,_deleteCount==1?“此频道”:“这些频道”);
title=\u deleteCount==1?“删除频道”:“删除频道”;
打破
//其他类型。。。
违约:
打破
}
_reallyDelete=MessageBox.Show(msg、title、MessageBoxButtons.YesNo)==System.Windows.Forms.DialogResult.Yes;
}
e、 取消=!\u真正删除;
//等待所有事件触发后再开始删除
如果(---\u deleteCount==0)
{
开关(此.Type)
{
案例管理员类型。频道:
列表通道=_deleteEntities.Cast().ToList();
删除_频道(频道);
打破
//其他类型。。。
违约:
打破
}
_删除=假;
_reallyDelete=false;
_deleteEntities=null;
}
}

r用此事件键\u替换UserDeletingRow的事件

如果(e.KeyValue==46)//删除键

{ e、 Handled=MessageBox.Show(“是否确实要删除所选行”, “确认”,MessageBoxButtons.OK取消,MessageBoxIcon.Question)!=DialogResult.OK;
}

r用此事件键\u替换UserDeletingRow的事件

如果(e.KeyValue==46)//删除键

{ e、 已处理=消息