C# Datagridview 在单击时导致 IndexOutOfRangeException
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/930069/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Datagridview causing IndexOutOfRangeException when clicked upon
提问by CasperT
I have a datagridview which we will call dataGridViewExample.
我有一个 datagridview,我们将其称为 dataGridViewExample。
My object (the uncommon datatypes is because my database is SQLite):
我的对象(不常见的数据类型是因为我的数据库是 SQLite):
class MyObject
{
public Int64 Vnr { get; set; }
public string Name { get; set; }
public Single Price { get; set; }
public int Amount { get; set; }
}
Here is the relevant code:
这是相关的代码:
//This form gets called with a .ShowDialog(); in my form1.
private List<MyObjecte> ExampleList = new List<MyObject>();
public MyForm()
{
dataGridViewExample.DataSource = OrdreInk?bsListe;
}
private void AddtoDataGridViewExample()
{
//Add a new MyObject to the list
ExampleList.Add(new myObject()
{
Vnr = newVnr,
Amount = newAmount,
Price = newPrice,
Name = newName
});
//refresh datasource
dataGridViewExample.DataSource = null;
dataGridViewExample.Refresh();
dataGridViewExample.DataSource = OrdreInk?bsListe;
ddataGridViewExample.Refresh();
}
When MyForm gets called with a .ShowDialog, it shows up fine and displays my DataGridView example just fine. As you can read from the code, the ExampleList
is initially empty, so it just shows an empty datagridview with 4 columns: Vnr, Name, Price & Amount. If I click inside it etc. nothing happens - so everything is working as planned, so far.
当使用 .ShowDialog 调用 MyForm 时,它显示正常并显示我的 DataGridView 示例。从代码中可以看出,ExampleList
最初是空的,所以它只显示一个空的 datagridview,有 4 列:Vnr、名称、价格和金额。如果我在里面点击等等,什么都没有发生 - 所以到目前为止一切都按计划进行。
Everytime I call AddtoDataGridViewExample()
it adds the new object to the Datagridview, and the datagridview does update, listing all the objects added so far (they show themself as rows, again according to plan).
每次我调用AddtoDataGridViewExample()
它时都会将新对象添加到 Datagridview,并且 datagridview 会更新,列出到目前为止添加的所有对象(它们将自己显示为行,再次按照计划)。
Now, remember that I just said that nothing happened if you clicked inside DataGridViewExample
before I have called AddtoDataGridViewExample()
?
Well, after having called AddtoDataGridViewExample()
once or more, the program will crash if I click inside DataGridViewExample
(for example: the users wants to select a row). It throws an IndexOutOfRangeExceptionand talks about an -1 index.
It also throws the exception in the other form, on the line where I call MyForm with .ShowDialog()
;
现在,还记得我刚刚说过如果你DataGridViewExample
在我打电话之前点击里面什么都不会发生AddtoDataGridViewExample()
吗?好吧,在调用AddtoDataGridViewExample()
一次或多次之后,如果我在里面单击,程序就会崩溃DataGridViewExample
(例如:用户想要选择一行)。它抛出一个IndexOutOfRangeException并谈论一个 -1 索引。它还在另一种形式中抛出异常,在我调用 MyForm 的那一行.ShowDialog()
;
I really am stuck on this, do you guys have any idea what is wrong??
My only clue isthat I do believe the refresh of DataGridViewExample
's datasource might be the cause of the problem.
Another importantnote: I have yet bound any events to my DataGridViewExample
. So you can rule that idea out.
我真的被困在这个问题上,你们知道出了什么问题吗?
我唯一的线索是我确实相信DataGridViewExample
's 数据源的刷新可能是问题的原因。另一个重要说明:我尚未将任何事件绑定到我的DataGridViewExample
. 所以你可以排除这个想法。
Here is all DataGridViewExample
's properties:
这是 allDataGridViewExample
的属性:
this.dataGridViewExample.AllowUserToAddRows = false;
this.dataGridViewExample.AllowUserToDeleteRows = false;
this.dataGridViewExample.AllowUserToResizeColumns = false;
this.dataGridViewExample.AllowUserToResizeRows = false;
this.dataGridViewExample.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill;
this.dataGridViewExample.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dataGridViewExample.Location = new System.Drawing.Point(591, 53);
this.dataGridViewExample.MultiSelect = false;
this.dataGridViewExample.Name = "dataGridViewExample";
this.dataGridViewExample.ReadOnly = true;
this.dataGridViewExample.RowHeadersVisible = false;
this.dataGridViewExample.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
this.dataGridViewExample.ShowEditingIcon = false;
this.dataGridViewExample.Size = new System.Drawing.Size(240, 150);
this.dataGridViewExample.TabIndex = 31;
采纳答案by Noam Gal
I guess the click event tries to get the currently selected row and do something with it, while dataGridViewExample.DataSource = null;
clears the datasource, and the currently selected row becomes null.
我猜点击事件会尝试获取当前选定的行并对其进行处理,同时dataGridViewExample.DataSource = null;
清除数据源,并且当前选定的行变为空。
If you set the DataGridView.DataSource
to the list, you don't need to reset it to null, refresh, and reset it to the list again (and refresh again) to see the changes. It will be enough to just refresh the DataGridView
.
如果将 设置DataGridView.DataSource
为列表,则无需将其重置为空值、刷新并再次将其重置为列表(并再次刷新)以查看更改。只需刷新DataGridView
.
You can also just try using an BindingList<T>
object instead of a List<T>
, which will automatically notify your grid of its internal changes (Adding and removing elements), and there's also an INotifyPropertyChanged
interface you can implement on your MyObject
class, that will make every property change in an object show on the grid (For any changes made to the object in the code, and not through the grid itself).
您也可以尝试使用BindingList<T>
对象而不是 a List<T>
,它会自动通知您的网格其内部更改(添加和删除元素),并且还有一个INotifyPropertyChanged
您可以在您的MyObject
类上实现的接口,它将使对象中的每个属性更改在网格上显示(对于代码中的对象所做的任何更改,而不是通过网格本身)。
回答by ChrisF
Have you tried running the debugger and break when InedxOutOfRangeException is thrown to see where the exception is thrown?
您是否尝试过运行调试器并在抛出 InedxOutOfRangeException 时中断以查看抛出异常的位置?
Select Debug > Exceptions then there's a Find button on the dialog so you don't have to browse through all of the possibilities.
选择 Debug > Exceptions 然后对话框上有一个 Find 按钮,因此您不必浏览所有可能性。
回答by Marek Bar
I had similar situation. I assigned generic list of certain object to DataGridView. Then I was setting null to DataSource and after that refresh. After that I assign list of objects to DataSource. While clicked on grid while runtime error occured IndexOutOfRange. My solution was to assign new empty list of my object to that grid and refresh and after changes on my working list I do assign to DataSource and call Refresh. Now, it is working without any crashes. Please look on my code before:
我有类似的情况。我将某个对象的通用列表分配给了 DataGridView。然后我将 null 设置为 DataSource 并在刷新之后。之后,我将对象列表分配给 DataSource。在出现运行时错误时单击网格时出现 IndexOutOfRange。我的解决方案是将我的对象的新空列表分配给该网格并刷新,在我的工作列表更改后,我确实分配给 DataSource 并调用 Refresh。现在,它可以正常工作,没有任何崩溃。请先查看我的代码:
grid.DataSource = null;
grid.Refresh();
if(cases.Count() > 0)
{
grid.DataSource = cases;
grid.Refresh();
}
And now on my code after:
现在在我的代码之后:
grid.DataSource = new List<MyCase>();
grid.Refresh();
//do something with cases
if(cases.Count() > 0)
{
grid.DataSource = cases;
grid.Refresh();
}