How to: Display Data Which is Being Updated on Another Thread

  • 3 minutes to read
NOTE

A recommended way to manage multi-thread updates is to dispatch them to the main thread. With this approach, you can perform time-consuming operations such as loading data in a separate thread.

NOTE

This approach does not work for the TreeListView. Dispatch data updates to the main thread to avoid the issue in this scenario.

This example invokes the BeginDataUpdate and EndDataUpdate methods to temporarily disable internal data updates in the GridControl.

We used the following approaches in order not to call the GridControl's methods in the ViewModel.

In v13.1.4 and later, we created a custom service. This service implements the ICustomService interface and invokes BeginDataUpdate and EndDataUpdate in the ICustomService.BeginUpdate and ICustomService.EndUpdate methods.

public interface ICustomService {
    void BeginUpdate();
    void EndUpdate();
}
Public Interface ICustomService
    Sub BeginUpdate()
    Sub EndUpdate()
End Interface

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

In the previous versions, the ViewModel class provides additional events and invokes them before and after the data update. The MainWindow subscribes to these events and invokes BeginDataUpdate and EndDataUpdate in the event handlers.

<dxg:GridControl Name="grid" AutoGenerateColumns="AddNew" ItemsSource="{Binding Source}">
    <mvvm:Interaction.Behaviors>
        <local:CustomService />
    </mvvm:Interaction.Behaviors>
</dxg:GridControl>
public interface ICustomService {
    void BeginUpdate();
    void EndUpdate();
}

public class CustomService : ServiceBase, ICustomService {
    public static readonly DependencyProperty GridControlProperty =
        DependencyProperty.Register("GridControl", typeof(GridControl), typeof(CustomService), new PropertyMetadata(null));

    public GridControl GridControl {
        get { return (GridControl)GetValue(GridControlProperty); }
        set { SetValue(GridControlProperty, value); }
    }
    protected GridControl ActualGridControl { get { return GridControl != null ? GridControl : AssociatedObject as GridControl; } }

    public void BeginUpdate() {
        Dispatcher.Invoke(new Action(() => {
            if (ActualGridControl != null) {
                ActualGridControl.BeginDataUpdate();
            }
        }));
    }

    public void EndUpdate() {
        Dispatcher.Invoke(new Action(() => {
            if (ActualGridControl != null) {
                ActualGridControl.EndDataUpdate();
            }
        }));
    }
}