从其他线程更新wpf datagrid单元格

时间:2010-07-27 04:15:39

标签: c# .net wpf multithreading

我正在尝试使用WPF datagrid实现一个简单的电子表格。 当用户在单元格中输入公式时,引擎会计算公式并使用计算值更新单元格。但是我处理的大多数计算需要很长时间,所以我想在其他线程中计算它们。

我尝试使用如下的CellEditEnding事件来实现此功能。 (dataGrid1的ItemsSource绑定到DataTable dtab。)

private void dataGrid1_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e) {
    Action calc = () => {
        int r = dataGrid1.Items.IndexOf(e.Row.Item);
        int c = dataGrid1.Columns.IndexOf(e.Column);
        dtab.Rows[r].SetField(c, "X"); // a calculated value
    };            
    Action update = () => {
        if (dataGrid1.Dispatcher.CheckAccess()) calc();
        else dataGrid1.Dispatcher.BeginInvoke(calc);
    };

    //update(); // run from the same ui thread
    Task.Factory.StartNew(update); // run from a different thread
}

当它从同一个UI线程更新单元格值时,单元格会更新为值“X”,但是从不同的线程更新,则不是。如何从不同的线程更新值为“X”的单元格?

编辑:我的代码没有抛出任何InvalidOperationException bcz我使用了Dispatcher.BeginInvoke()。我的问题似乎是用户输入值(公式)覆盖了我想要显示的计算值。

3 个答案:

答案 0 :(得分:1)

您无法从其他线程更新GUI。幸运的是.Net提供了一种处理这个问题的机制:

uiControl.**Dispatcher**.Invoke(delegate)

例如

dataGrid1.Dispatcher.Invoke(() => MyUpdateFunction(dataGrid1, data))

编辑:抱歉原始代码适用于Windows.Forms

答案 1 :(得分:1)

使用调度程序不是一个好主意。如果编码不正确,它可以使您的UI无响应。如果您计划在多线程设置中使用datagrid,那么您应该使用事件来反映更新。我建议将ObservableCollection与INotifyPropertyChanged组合作为更好的选择。我在这里发布了一个模板:

this

答案 2 :(得分:0)

看看WPF Dispatcher Class。您有很多选项可以从Dispatcher执行线程化任务。查看BeginInvoke和Invoke方法。