首页 > 解决方案 > 具有拖放操作的 DataGridView ArgumentOutOfRangeException

问题描述

我的代码在 DataGridViewRowCollection.cs 中引发 ArgumentOutOfRangeException。

它在计算方法 DataTableFlagRowDeleted 后抛出。

我不知道如何解决它。除了例外,代码按预期工作。

异常后的结果,如预期

我正在开发 .NETCore.App 3.1 版。

请帮忙。

非常感谢。

这是我的代码:

using System;
using System.Data;
using System.Windows.Forms;

namespace DgvTestApp
{
    public partial class Form1 : Form
    {
        DataTable dtSource = new DataTable();
        DataTable dtTarget = new DataTable();
        private enum ColumnName { Id, Product };
        
        public Form1()
        {
            InitializeComponent();
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            dgvSource.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
            dgvSource.CellMouseDown += DgvSource_CellMouseDown;

            

            dtSource.Columns.Add(ColumnName.Id.ToString(), typeof(string));
            dtSource.Columns.Add(ColumnName.Product.ToString(), typeof(string));

            DataRow r1 = dtSource.NewRow();
            r1[ColumnName.Id.ToString()] = "4711";
            r1[ColumnName.Product.ToString()] = "1st Product";
            dtSource.Rows.Add(r1);

            dgvSource.DataSource = dtSource;
            dtSource.PrimaryKey = new DataColumn[] { dtSource.Columns[ColumnName.Id.ToString()] };

            DataRow r2 = dtSource.NewRow();
            r2[ColumnName.Id.ToString()] = "0815";
            r2[ColumnName.Product.ToString()] = "2nd Product";
            dtSource.Rows.Add(r2);
            dtSource.AcceptChanges();

            dgvTarget.AllowDrop = true;
            dgvTarget.ReadOnly = true;
            dgvTarget.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
            dgvTarget.MultiSelect = false;
            dgvTarget.AllowUserToAddRows = false;
            dgvTarget.DataSource = dtTarget;
            dgvTarget.DragDrop += DgvTarget_DragDrop;
            dgvTarget.DragEnter += DgvTarget_DragEnter;

            dtTarget.Columns.Add(ColumnName.Id.ToString(), typeof(string));
            dtTarget.Columns.Add(ColumnName.Product.ToString(), typeof(string));

        }

        private void DgvTarget_DragEnter(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.Copy;
        }

        private void DgvTarget_DragDrop(object sender, DragEventArgs e)
        {
            DataGridViewRow oDraggedSource = (DataGridViewRow)e.Data.GetData(e.Data.GetFormats()[0]);

            CreateDgvRowInTargetFromSource(oDraggedSource);
            DataTableFlagRowDeleted(dtSource, ColumnName.Id.ToString(), oDraggedSource.Cells[ColumnName.Id.ToString()].Value);
        }

        private void DgvSource_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
        {
            dgvSource.DoDragDrop(dgvSource.Rows[e.RowIndex], DragDropEffects.Copy);
        }

        private void CreateDgvRowInTargetFromSource(DataGridViewRow oDraggedSource)
        {
            DataRow oNewRowTarget = dtTarget.NewRow();

            oNewRowTarget[ColumnName.Id.ToString()] = oDraggedSource.Cells[ColumnName.Id.ToString()].Value;
            oNewRowTarget[ColumnName.Product.ToString()] = oDraggedSource.Cells[ColumnName.Product.ToString()].Value;

            dtTarget.Rows.Add(oNewRowTarget);
            oNewRowTarget.AcceptChanges();
        }

        private void DataTableFlagRowDeleted(DataTable dt, string key, object value, bool bDataRowAcceptChanges = false)
        {
            for (int i = dt.Rows.Count - 1; i >= 0; i--)
            {
                DataRow dr = dt.Rows[i];
                if (dr.RowState != DataRowState.Deleted)
                    if (dr[key].ToString() == value.ToString())
                        //dt.Rows.Remove(dr); // Remove() == Delete() + AcceptChanges()!
                        dr.Delete();

            }

            if (bDataRowAcceptChanges)
                dt.AcceptChanges();
        }
    }
}

标签: c#winforms

解决方案


推荐阅读