2

I have a DataGrid in my WPF application. For this DataGrid I have set ItemSource as below

ItemsSource="{Binding Path=MyItems}"

MyItems is List of MyItem declared in MyViewModel

    // ItemsSource for MyItem Grid
    public List<MyItem> MyItems {get;set; }

MyItem has set of Properties, Each property is mapped with each column in DataGrid. At initialization I am filling MyItems; So DataGrid is showing MyItems values in each column.

In a button command, I am creating a Worker thread, Worker thread modifies properties of MyItems which are shown in the Grid. For example MyItem has a property called "Status" which is binded to a column of grid. The status value is changed in the workerthread. End of the worker thread I am calling

OnPropertyChanged("MyItems"); //force UI refresh

But status column values in the grid is not updating.

Once I click the datagrid column then only the values are refreshing. How to refresh datagrid from worker thread?

weston
  • 54,145
  • 21
  • 145
  • 203
srajeshnkl
  • 883
  • 3
  • 16
  • 49
  • Show the code for the `MyItem`. That needs to be observable. (plus that notification needs to be sent in the UI thread. – weston Mar 09 '15 at 08:49

2 Answers2

2

If you do it right, you won't need to tell the grid to refresh. There are also unintended consequences if you did manage to refresh the whole grid, such as jumping to the top of the grid and loosing any user selected rows/cells as well as aborting edits if applicable.

ObservableCollection

This is how you should set up the list the grid is looking at:

private readonly ObservableCollection<MyItem> _myItems = new ObservableCollection<MyItem>();

public IEnumerable<MyItem> MyItems { get { return _myItems; } }

That will mean that new items, and removals update the grid automatically. However to update an individual cell, that property needs to be observable, i.e. the class MyItem must implement INotifyPropertyChanged.

Multithreading

For multithreading you'll need to set the properties on MyItem in the UI thread, even if you do the calculation in a worker thread (see below). You can achieve this with a Dispatcher. See Updating GUI (WPF) using a different thread

Worker thread

As for starting your own thread, do not do that, use a Task.

Community
  • 1
  • 1
weston
  • 54,145
  • 21
  • 145
  • 203
0

Using dispatcher is not a good idea. UI may become non responsive if not coded properly. Using datagrid in multithreaded environment is tricky.

  1. Background thread to process data and based on the result of this processing, the data grid will be updated.
  2. UI controls in WPF can be updated by UI thread only.
  3. There can be more than one UI control which will work together to achieve the overall functionality (Progress bar, buttons, etc.). Coders often make a mistake of passing control reference in an insecure way.
  4. The source of data to which the datagrid will be bound should not be modifiable by any other class.

I have published a template here. It covers a possible approach on using datagrid in multithreaded setup.

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

amarnath chatterjee
  • 1,942
  • 16
  • 15