C# DataGridView选择更改直到SelectionChanged事件处理程序完成后才会显示

C# DataGridView选择更改直到SelectionChanged事件处理程序完成后才会显示,c#,.net,winforms,datagridview,C#,.net,Winforms,Datagridview,我正在捕获DataGridView控件的SelectionChanged事件,我的事件处理程序需要大约1/2秒的时间来完成设置几个控件的值等任务。。在用户界面方面,这是一个永恒 问题是DataGridView的用户界面不会立即更新选择。我希望用户在单击DataGridView时立即看到选择的更改,然后看到要完成的冗长工作。完成整个任务仍然需要1/2秒,用户界面在这段时间内不会有响应,这没关系,至少用户会立即得到反馈 通过将以下代码插入到新的Form1类中,可以看到此行为: private

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

问题是DataGridView的用户界面不会立即更新选择。我希望用户在单击DataGridView时立即看到选择的更改,然后看到要完成的冗长工作。完成整个任务仍然需要1/2秒,用户界面在这段时间内不会有响应,这没关系,至少用户会立即得到反馈

通过将以下代码插入到新的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值,但是对于一个简单的任务来说,这似乎有很多复杂性


当然有更好的方法。

虽然我认为将长时间运行的任务放入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线程。在这一点上,我认为DataGridView还没有被指示自行绘制,因此您没有看到它的更新。

谢谢。这很有效。现在我明白了。DataGridView直到事件处理程序完成后才发布绘制消息,因此我的长时间运行任务仍然在绘制消息之前执行,除非我按照您的建议强制执行。