【问题标题】:How to prevent datagridview from firing UserDeletingRow-event for every selected row?如何防止 datagridview 为每个选定的行触发 UserDeletingRow-event?
【发布时间】:2013-03-18 10:32:27
【问题描述】:

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

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

这个事件处理程序为每个选定的行触发,它也总是触发“你真的要删除吗”-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;
    }
}

此方法确认后调用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;
}

【问题讨论】:

  • 所以Delete_Channels 等处理您的删除过程,但您想将其与Delete_Objects 结合起来 - 例如?
  • 您可能应该考虑构建您想要的行为。 AFAIK 没有任何事件可用于多次删除处理。可能对您来说就足够了: 1. 获取选定行的数量。 2.在每个事件中减少它并将可删除的行信息收集到某个列表中 3.在最后一行事件中将其添加到集合中,就像所有以前的事件一样,并立即删除它们,调用服务或您需要做的方式。跨度>
  • @LukeHennerley:是的,也不是。 Delete_Channels 确认后通过网络服务删除所有频道注入。但是它将所有频道都作为List&lt;Channel&gt;,所以我想一次通过所有选定的频道。
  • @Tigran:我很惊讶 winforms 如此繁琐(我的 winforms 经验很生疏)。我希望会有一些内置的或更强大的东西。
  • @Tigran:添加了我对您建议的实施,它似乎运作良好。谢谢:)

标签: c# winforms data-binding datagridview event-handling


【解决方案1】:

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

解决方法如下:

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;
    }
}

【讨论】:

  • 我认为这有一个错误。如果取消消息框Delete_Channels(channels) 仍会在最后一次迭代中调用。
【解决方案2】:

用此事件 key_Down 替换 UserDeletingRow 事件

if ( e.KeyValue == 46 ) // 删除键

{ e.Handled = MessageBox.Show("你真的要删除选中的行吗", "确认", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) != DialogResult.OK; }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-25
    • 1970-01-01
    • 2021-11-25
    • 1970-01-01
    • 2014-12-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多