简体   繁体   English

从其他线程更新wpf datagrid单元

[英]update wpf datagrid cell from other thread

I'm trying to implement a simple spreadsheet using WPF datagrid. 我正在尝试使用WPF数据网格实现一个简单的电子表格。 When users input a formula in a cell, engine calculates the formula and update the cell with the calculated value. 当用户在单元格中输入公式时,引擎将计算公式并使用计算出的值更新单元格。 But most of calculations i handle take long time, so i want to calculate those in other threads. 但是我处理的大多数计算都需要很长时间,因此我想在其他线程中进行计算。

I tried to implement this using CellEditEnding event like below. 我尝试使用CellEditEnding事件来实现此目标,如下所示。 (the ItemsSource of dataGrid1 is bound to the DataTable dtab.) (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
}

When it update the cell value from the same UI thread, cell is updated with value "X", but from the different thread, it is not. 当它从同一UI线程更新单元格值时,单元格将用值“ X”更新,但从不同线程更新时,它不是。 How can i update the cell with value "X" from a different thread? 如何从其他线程更新值为“ X”的单元格?

EDIT: My code does not throw any InvalidOperationException bcz i used the Dispatcher.BeginInvoke(). 编辑:我的代码不会抛出任何InvalidOperationException,因为我使用了Dispatcher.BeginInvoke()。 My problem seems that the user input value (formula) overwrites the calculated value which i want to display. 我的问题似乎是用户输入值(公式)覆盖了我要显示的计算值。

You cannot update the GUI from another thread. 您不能从另一个线程更新GUI。 Fortunately .Net provides a mechanism to handle this: 幸运的是,.Net提供了一种处理此问题的机制:

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

For example 例如

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

Edit: Sorry the original code was for Windows.Forms 编辑:抱歉,原始代码适用于Windows.Forms

Using dispatcher is not a good idea. 使用调度程序不是一个好主意。 It can render your UI non responsive if not coded properly. 如果编码不正确,它会使用户界面无响应。 If you plan to use datagrid in multithreaded setup then you should use events to reflect the updates. 如果计划在多线程设置中使用datagrid,则应使用事件来反映更新。 I would recommend a combination of ObservableCollection with INotifyPropertyChanged as better alternative. 我建议结合使用ObservableCollection和INotifyPropertyChanged作为更好的选择。 I have published a template here : 我在这里发布了一个模板:

http://www.codeproject.com/Articles/1086714/A-Template-For-Using-Datagrid-in-Monitoring-UI http://www.codeproject.com/Articles/1086714/A-Template-For-Using-Datagrid-in-Monitoring-UI

Take a look at the WPF Dispatcher Class . 看一下WPF Dispatcher类 You have quite a few options to perform threaded tasks from the Dispatcher. 您有很多选择可以从Dispatcher执行线程化任务。 Review the BeginInvoke and Invoke methods. 查看BeginInvoke和Invoke方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM