超出范围异常.必须是非负数并且小于集合的大小.参数名称:index



我无法解决此错误。我正在通过文本更改事件用文本框过滤datagridview。过滤后的结果显示在datagridview中后,我将在图像列中添加类似按钮的图像外观。以编程方式添加按钮的原因是,我的应用程序中有深色和浅色主题,如果深色主题设置为其他浅色按钮图像,我必须设置深色按钮图像。

这个异常并不是一直都在引发,但通常是在我更快地向文本框添加和删除文本时。

在函数AddButtonToGrid((中的这些代码行引发异常

((DataGridViewImageCell)DataGridViewAllMusic.Rows[row].Cells[1]).Value = Properties.Resources.DarkPLPS;
((DataGridViewImageCell)DataGridViewAllMusic.Rows[row].Cells[1]).Value = Properties.Resources.LightPLPS;

异常详细信息:

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.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource)
at System.Windows.Forms.DataGridViewRowCollection.get_Item(Int32 index)
at MY_Player.Forms.MainForm.<AddButtonToGrid>b__29_0() in C:UsersHPDesktop
PlayerFormsMainForm.cs:line 290
at System.Threading.Tasks.Task.Execute()

我的代码:

文本框Search_TextChanged

private void TextboxSearch_TextChanged(object sender, EventArgs e)
{
try
{
if (TextboxSearch.Text != "" && DataGridViewAllMusic.DataSource != null)
{
DataGridViewAllMusic.Invoke((MethodInvoker)delegate
{
this.DataGridViewAllMusic.SelectionChanged -= new EventHandler(DataGridViewAllMusic_SelectionChanged);
(DataGridViewAllMusic.DataSource as DataTable).DefaultView.RowFilter = string.Format("Value LIKE '{0}%' or Artist LIKE '{1}%' or Album LIKE '{2}%' or Comments LIKE '{3}%' ",
TextboxSearch.Text, TextboxSearch.Text, TextboxSearch.Text, TextboxSearch.Text);
AddButtonToGrid();
this.DataGridViewAllMusic.SelectionChanged += new EventHandler(DataGridViewAllMusic_SelectionChanged);
});
}
else
{
if (DataGridViewAllMusic.DataSource != null)
{
DataGridViewAllMusic.Invoke((MethodInvoker)delegate
{
this.DataGridViewAllMusic.SelectionChanged -= new EventHandler(DataGridViewAllMusic_SelectionChanged);
(DataGridViewAllMusic.DataSource as DataTable).DefaultView.RowFilter = null;
AddButtonToGrid();
this.DataGridViewAllMusic.SelectionChanged += new EventHandler(DataGridViewAllMusic_SelectionChanged);  
});
}
}
}
catch
{
}
}

将按钮添加到网格((

private async  void AddButtonToGrid()
{
await Task.Run(() =>
{
if (DataGridViewAllMusic.Rows.Count > 0)
{
if (DarkMode)
{
DataGridViewAllMusic.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.DisableResizing;
DataGridViewAllMusic.RowHeadersVisible = false;
for (int row = 0; row <= DataGridViewAllMusic.Rows.Count - 1; row++)
{
((DataGridViewImageCell)DataGridViewAllMusic.Rows[row].Cells[1]).Value = Properties.Resources.DarkPLPS;
}
}
else
{
DataGridViewAllMusic.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.DisableResizing;
DataGridViewAllMusic.RowHeadersVisible = false;
for (int row = 0; row <= DataGridViewAllMusic.Rows.Count - 1; row++)
{
((DataGridViewImageCell)DataGridViewAllMusic.Rows[row].Cells[1]).Value = Properties.Resources.LightPLPS;
}
}
}
}).ConfigureAwait(false);
}

您正试图在多个线程中执行UI代码。

只是不要。

您应该仅从主线程操作UI元素。因此,对于您的代码,只需删除await Task.Run(() =>,如果您的TextboxSearch_TextChanged方法实际上仅由事件调用,则也不需要Invoke调用。UI事件在主线程上执行。此外,如果您有async方法,请尽可能小心使用await方法,否则会产生难以调试的问题。

如果你想在你的应用程序中尝试多线程,你应该把它分成几个关注的领域。UI可能是其中之一,数据操作可能是另一种。有一些模式和框架可以促进关注点的分离。

最新更新