我无法解决此错误。我正在通过文本更改事件用文本框过滤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可能是其中之一,数据操作可能是另一种。有一些模式和框架可以促进关注点的分离。