Example E3322
Visible to All Users

Data Grid for WPF - How to Update Data in a Separate Thread

This example demostrates how to update GridControl data in a separate thread. To
synchronize access to data, call the BeginDataUpdate and EndDataUpdate methods. These methods allow you to lock updates within the GridControl, process data updates, and then apply all changes to the control.

Create a custom service that calls the GridControl methods. Use the Dispatcher to invoke these methods in the UI thread.

C#
... public interface IGridUpdateService { void BeginUpdate(); void EndUpdate(); } public class GridUpdateService : ServiceBase, IGridUpdateService { //... public void BeginUpdate() { Dispatcher.Invoke(new Action(() => { if (GridControl != null) { GridControl.BeginDataUpdate(); } })); } public void EndUpdate() { //... } } ...

Add the service to your View and assosiate this service with the GridControl.

XAML
<dxg:GridControl> <mvvm:Interaction.Behaviors> <local:GridUpdateService /> </mvvm:Interaction.Behaviors> </dxg:GridControl> ...

Access the service at the View Model level. If you inherit your View Model class from ViewModelBase, you can access the service as follows:

C#
public class ViewModel : ViewModelBase { //... public IGridUpdateService GridUpdateService { get { return GetService<IGridUpdateService>(); } } void TimerCallback(object state) { lock(SyncRoot) { if(GridUpdateService != null) { GridUpdateService.BeginUpdate(); foreach(DataItem item in Source) { item.Value = random.Next(100); } GridUpdateService.EndUpdate(); } } } }

Files to Look At

Documentation

Refer to the following topics for information on how to access a service in the ViewModel:

More Examples

Does this example address your development requirements/objectives?

(you will be redirected to DevExpress.com to submit your response)

Example Code

GridUpdateService.cs(vb)
C#
using DevExpress.Xpf.Grid; using System; using System.Windows; using DevExpress.Mvvm.UI; namespace DXGridThreads { public interface IGridUpdateService { void BeginUpdate(); void EndUpdate(); } public class GridUpdateService : ServiceBase, IGridUpdateService { GridControl GridControl => AssociatedObject as GridControl; public void BeginUpdate() { Dispatcher.Invoke(new Action(() => { if (GridControl != null) { GridControl.BeginDataUpdate(); } })); } public void EndUpdate() { Dispatcher.Invoke(new Action(() => { if (GridControl != null) { GridControl.EndDataUpdate(); } })); } } }
MainWindow.xaml
XAML
<Window x:Class="DXGridThreads.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core" xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid" xmlns:local="clr-namespace:DXGridThreads" xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm" Title="MainWindow" Width="525" Height="350"> <Window.DataContext> <local:ViewModel /> </Window.DataContext> <dxg:GridControl AutoGenerateColumns="AddNew" ItemsSource="{Binding Source}"> <dxmvvm:Interaction.Behaviors> <local:GridUpdateService /> </dxmvvm:Interaction.Behaviors> </dxg:GridControl> </Window>
ViewModel.cs(vb)
C#
using DevExpress.Mvvm; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Threading; namespace DXGridThreads { public class DataItem : BindableBase { public string Name { get { return GetValue<string>(); } set { SetValue(value); } } public int Value { get { return GetValue<int>(); } set { SetValue(value); } } } public class ViewModel : ViewModelBase { public ObservableCollection<DataItem> Source { get; set; } public IGridUpdateService GridUpdateService { get { return GetService<IGridUpdateService>(); } } public ViewModel() { timer = new Timer(TimerCallback, null, 1000, 1000); Source = new ObservableCollection<DataItem>(GetData()); } static object SyncRoot = new object(); Timer timer; Random random = new Random(); void TimerCallback(object state) { lock(SyncRoot) { if(GridUpdateService != null) { GridUpdateService.BeginUpdate(); foreach(DataItem item in Source) { item.Value = random.Next(100); } GridUpdateService.EndUpdate(); } } } static IEnumerable<DataItem> GetData() { for(var i = 0; i < 100; ++i) { yield return new DataItem() { Name = $"Name {i}", Value = i }; } } } }

Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.

Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.