在SelectionChanged事件处理程序完成之前,DataGridView选择更改不会显示

时间:2012-05-23 00:54:02

标签: c# .net winforms datagridview

我正在捕获DataGridView控件的SelectionChanged事件,我的事件处理程序需要大约1/2秒来完成其任务(设置几个控件的值等)。在用户界面中,这是永恒的。

问题是DataGridView的用户界面不会立即更新选择。我想要的是让用户在点击后立即查看DataGridView中的选择更改,然后 然后 完成漫长的工作。它仍然需要1/2秒才能完成整个任务,UI在此期间不会响应,这没关系 - 至少用户会立即得到反馈。

通过将以下代码插入到新的Form1类中,可以看到此行为:

    private System.Windows.Forms.DataGridView dataGridView1;

    public Form1()
    {
        InitializeComponent();
        dataGridView1 = new DataGridView();
        dataGridView1.Dock = DockStyle.Fill;
        dataGridView1.Columns.Add("Column0", "Column 0");
        dataGridView1.Rows.Add("Row 0");
        dataGridView1.Rows.Add("Row 1");
        dataGridView1.Rows.Add("Row 2");
        dataGridView1.Rows.Add("Row 3");
        dataGridView1.SelectionChanged += 
            new EventHandler(dataGridView1_SelectionChanged);
        this.Controls.Add(dataGridView1);
    }
    private void dataGridView1_SelectionChanged(object sender, EventArgs e)
    {
        if (this.Handle != null)
        {
            this.DoSomethingForAWhile();
            // Even BeginInvoke doesn't help
            //this.BeginInvoke((MethodInvoker)this.DoSomethingForAWhile);
        }
    }
    private void DoSomethingForAWhile()
    {
        // Do anything that causes a noticable delay

        DateTime t0 = DateTime.Now;
        while ((DateTime.Now - t0).TotalSeconds < 2)
        {
            // Do nothing
        }
    }

我通常会使用Control.BeginInvoke,以便在我的1/2秒任务开始之前处理绘制消息。这适用于ListView控件,但由于某种原因,它不适用于DataGridView。

可以在另一个线程上进行处理并使用Invoke来设置UI值,但对于应该是一个简单任务的东西来说,这看起来很复杂

当然有更好的方法。

1 个答案:

答案 0 :(得分:0)

虽然我认为将长时间运行的任务粘贴到BackgroundWorker并回调到UI以进行更新是合适的,但是通过调用DataGridView.Refresh()和使用BeginInvoke可以获得所需的行为;

private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
    dataGridView1.Refresh();
    if (this.Handle != null)
    {
        this.BeginInvoke((MethodInvoker)this.DoSomethingForAWhile);
    }
}

这种方法在长期运行的任务之前将UI消息粘贴在UI线程上,这阻止了UI线程。那时,我不相信DataGridView还没有被指示绘制自己,因此你没有看到它更新。