我有一个DataGridView。我尝试通过克隆add-new-row行来向其中添加行。当添加一行时,我设置了其单元格的一些值。我尝试通过其列的名称访问DataGridViewCell实例。
在显示UI之前,我在DataGridView的子类中做了类似的事情:
MyDataGridViewRow r = Rows[NewRowIndex].Clone() as MyDataGridViewRow;
Rows.Add(r);
r.Cells[Columns["MyColumnName"].Index].Value = "Example text";
这行不通,因为我(在最后一行)收到此异常:
System.ArgumentOutOfRangeException:'指定的参数超出了 有效值范围。参数名称:rowIndex'
我想单元格将添加到相应的列,而不是添加到行。
如果我直接将DataGridViewRow.Cells[]
运算符与列名Tag
一起使用:
System.ArgumentException:'找不到名为Tag的列。参数 名称:columnName'
发生这种情况时,我在调试器中看到Cells集合包含所有列,每个Cell
都有
ColumnIndex
之前尝试使用RowIndex
运算符,则-1
和[]
等于Rows.Add
,并且RowIndex
运算符之前调用-1
,则只有Rows.Add
等于[]
(在这种情况下,ColumnIndex的值从0
开始)。这发生在显示任何形式之前。
因此,我试图制作一个具有相同错误的小项目。这在Form1类中:
DataGridView dgv;
public Form1()
{
InitializeComponent();
dgv = new DataGridView();
// from DataGridView subclass ctor
dgv.RowTemplate = new MyRow();
dgv.Left = 10;
dgv.Top = 10;
Controls.Add(dgv);
// from Initialize method
dgv.Columns.Clear();
DataGridViewTextBoxColumn c = new DataGridViewTextBoxColumn()
{
HeaderText = "My Header",
Name = "MyColumn"
};
dgv.Columns.Add(c);
// here the columns and row templates should be ready
MyRow r = dgv.Rows[dgv.NewRowIndex].Clone() as MyRow;
r.Cells["MyColumn"].Value = "My Value";
dgv.Rows.Add(r);
}
internal class MyRow : DataGridViewRow
{
internal MyRow() : base()
{
}
}
现在我在行dgv.Columns.Add(c)
上遇到另一个异常:
System.MissingMethodException:'未定义无参数构造函数 为此对象。”
例外情况:
System.MissingMethodException
HResult=0x80131513
Message=No parameterless constructor defined for this object.
Source=mscorlib
StackTrace:
at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
at System.Activator.CreateInstance(Type type, Boolean nonPublic)
at System.Activator.CreateInstance(Type type)
at System.Windows.Forms.DataGridViewRow.Clone()
at System.Windows.Forms.DataGridView.get_RowTemplateClone()
at System.Windows.Forms.DataGridViewRowCollection.AddInternal(Boolean newRow, Object[] values)
at System.Windows.Forms.DataGridView.AddNewRow(Boolean createdByEditing)
at System.Windows.Forms.DataGridView.OnColumnCollectionChanged_PostNotification(DataGridViewColumn dataGridViewColumn)
at System.Windows.Forms.DataGridViewColumnCollection.OnCollectionChanged_PostNotification(CollectionChangeEventArgs ccea, Boolean changeIsInsertion, Point newCurrentCell)
at System.Windows.Forms.DataGridViewColumnCollection.Add(DataGridViewColumn dataGridViewColumn)
at project_namespace.Form1..ctor() in {project folder path here}\Form1.cs:line 37
at project_namespace.Program.Main() in {project folder path here}\Program.cs:line 19
相关问题here。
我正在使用.NET Framework 4.6.1。
更新1 :
如果我将dgv.Columns.Add(c);
行更改为
dgv.HandleCreated += (s, e) => { dgv.Columns.Add(c); };
以MyRow r
开头的行上出现以下异常:
System.ArgumentOutOfRangeException:'索引超出范围。一定是 非负数且小于集合的大小。参数名称: 索引”
异常详细信息:
System.ArgumentOutOfRangeException
HResult=0x80131502
Message=Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
Source=mscorlib
StackTrace:
at System.Collections.ArrayList.get_Item(Int32 index)
at System.Windows.Forms.DataGridViewRowCollection.SharedRow(Int32 rowIndex)
at System.Windows.Forms.DataGridViewRowCollection.get_Item(Int32 index)
at cs_test_6.Form1..ctor() in .....\Form1.cs:line 45
at cs_test_6.Program.Main() in .....\Program.cs:line 19
如果我删除了构造函数中的最后三行,则在单行匿名函数中,现在在dgv.Columns.Add(c)
的行上会遇到相同的第一个错误。
更新2 :我学到的东西:
如果我从文件中加载列的顺序,并且可以对其进行重新排序,那么如何使用行模板按名称设置单元格的值?这段代码就像Rows.Add(val1, val2)
一样工作(但可能效率较低):
MyDataGridViewRow r = new MyDataGridViewRow()
{
};
r.CreateCells(this);
r.Cells[0] =
new DataGridViewTextBoxCell()
{
Value = val1
};
r.Cells[1] =
new DataGridViewTextBoxCell()
{
Value = val2
};
Rows.Add(r);
如果我尝试使用r.Cells["MyColumn"]
,则会收到问题开头显示的错误。
我的问题是:如何以及何时可以通过DataGridViewRow的子类中的列名引用单元格?我尝试在构造函数中执行此操作,但它不起作用,即使使用整数索引也是如此。我需要这样做,因为我想拥有可重新排序的列。