嘿伙计们,我有一个包含大约10个项目的数据网格视图。我想从网格中删除特定项目。现在,虽然我设法做到这一点,我也想控制每个项目的删除的执行速度,即我希望它足够慢,以便用户看到每个项目被删除。我尝试在每次迭代中停止线程,如此
for (int i = dataGridView1.Rows.Count - 1; i <= 0; i--){
if (dataGridView.Rows[i] == null){
continue;
}
if (dataGridView.Rows[i].Cells[3].Value.ToString().Contains("Remove")){
// stop the thread
System.Threading.Thread.Sleep(900);
dataGridView1.Rows.RemoveAt(i);
}
}
虽然此代码确实可以快速删除项目,但所有匹配的项目都会立即删除。我尝试使用计时器,但是没有运气,无论如何都要实现这个目标吗?
答案 0 :(得分:4)
问题的可能原因:
我认为这里的问题是,在删除所有行之前,您的for
循环永远不会离开。也就是说,你的程序永远不会让GUI(Winforms?)有机会自行更新,直到删除所有行。
这就是为什么你的Thread.Sleep
一个接一个地发生(你还在你的循环中),以及你计划删除行的那些。一旦你的循环结束,你的GUI就有机会自我更新。它会看到计划删除的几行,并立即将它们全部删除。
可能的解决方案:
您可以做的是创建一个后台任务,该任务处理要删除的行队列。后台任务等待一段指定的时间,然后删除队列。在此步骤中,您必须使用dataGridView1.Invoke(...)
。
最后,你修改你向我们展示的循环,这样在第一步中,它就会填满队列;循环之后,启动后台任务。
示例代码:
我将尝试显示一些临时示例代码。请注意,这可能不是开箱即用的,我没有彻底检查它是否正确。
// the queue of rows that need to be deleted:
var rowsToDelete = new List<DataGridViewRow>();
// fill the queue:
foreach (var row in dataGridView.Rows)
{
if (removeCriteriaMetBy(row) == true)
{
rowsToDelete.Add(row);
}
}
// work off the queue:
var queueWorker = new BackgroundWorker();
queueWorker.DoWork += (sender, e) =>
{
foreach (var row in rowsToDelete)
{
// sleep per item:
Thread.Sleep(900);
// call back on the UI thread in order to modify the GUI control:
dataGridView.Invoke(new Action( () =>
{
dataGridView.Rows.Remove(row);
}));
}
};
queueWorker.RunWorkerAsync();
这应该有效,因为你的行删除循环在后台运行,即。与UI线程并行。这意味着UI线程不必等待删除循环完成。每当计划删除行时,UI线程可以并行响应。 (对dataGridView.Invoke(someAction)
的调用实质上会在UI线程的消息队列中显示一条消息:“执行此项工作(someAction
)。”)
答案 1 :(得分:0)
你在哪里运行该代码?
也许你应该对Datagridview.Userdeletingrow等事件进行讨论。