How to load data in DataGrid

Comarch.POS.Presentation.Core.Controls.DataGrid development object is based on a .NET development object and is used to load a data set divided into columns and rows. DataGrid in POS is, additionally, used to load data asynchronously, it supports list paging (it loads data as the list scrolls), changes the way data is sorted and modifies the grouping mechanism by enriching it with data aggregation.

How to load data asynchronously

For data to be loaded asynchronously, you need to bind its source with the AsyncItemsSource property in the DataGrid. The source must be an object of  AsyncDataGridCollection<T> class, where T indicates a data type that will be presented in a single row. The logic that loads data should be defined in the first parameter of the AsyncDataGridCollection class constructor, whereas the loaded data should be assigned to the Data collection.

Example

Documents = new AsyncDataGridCollection<TradeDocumentListRow>(
    (token, o) =>
    {                   
                   // data loading
        var documents = GetDocumentsAsync(token, o);
 
                  //only one thread can modify the collection at a time
        lock (Documents.DataLock)
        {
                           //data loading cancellation
            if (token.IsCancellationRequested)
            return null;

                            //the list needs to be cleared each time it is refreshed
            Documents.Data.Clear();
 				
                            //data is added to a data collection the DataGrid will load		 
            Documents.Data.AddRange(data);			
        }
 
    return documents;
    }, OnReceiptsOperationCompleted, loggingService);

The above example presents the Documents property definition implemented in the viewmodel constructor and binded with AsyncItemsSource property of DataGrid. The first argument of the constructor is a simple data retrieval logic (paging is not included). This method will automatically be invoked asynchronously by the DataGrid as soon as the DataGrid is initiated. To manually decide when to load data, change the property LoadDataOnDataGridInitialization=false in the Documents object. When you decide to load the data, the Documents.Refresh(false) method needs to be invoked. The second argument of the constructor is a method that will be invoked in the main thread (UI) right after the data retrieval logic ends. The third parameter is an instance of error logging service ILoggingService, owing to which any potential exceptions occurred in the retrieval thread will be saved in the application log file.

How to sort data

You can define paging by default and change it any time by clicking on the selected column. The default setting can be changed in the view management panel. The development object, itself, does not do the task but orders it to the data source by sending only the information about the desired sorting method, which invokes the data retrieval method. Information on how to sort the loaded data you can be read from the Sorting property in the Documents object.

  • Sorting : List<GridSortDescription> – a list containing information on the column by which and how to sort the data

Components of GridSortDescription class:

  • PropertyName : string – column name defined in the SortMemberPath property of the column. If no column name is defined, it will take the property name using in binding.
  • Direction : ListSortDirection – sort direction, selectable options are by ascending or by descending
  • Column : DataGridColumn – reference to the column

List paging

Paging, which basically is dynamic data loading as the user scrolls through the list, consists in initiating by the DataGrid component as the user approaches the end of the list an asynchronous method that fetches data, informing the source that another portion of data will be needed if it exists. With this mechanism you can smoothly handle large data sets, where loading of entire data set wouldn’t be as effective and efficient.

The paging logic itself needs to be implemented in the source. In order to know which portion of data the component is requesting, you need to use ItemsToTake and ItemsToSkip properties in the object of AsyncDataGridCollection<T> class.

  • ItemsToTake : int – number of data rows requested by the component
  • ItemsToSkip : int – number of data rows to be ignored from the beginning of the data set (this number represents the number of rows that were already loaded before)

Grouping and aggregation

The DataGrid component supports the mechanism for grouping and aggregating the values of collection entity presented by the component. Activating the grouping deactivates the data paging mechanism. To activate grouping, set the IsGroupingEnabled=”True” property in the component. Grouping is fully manageable in the UI management view and allows grouping and aggregation by the previously defined properties. For a property to be grouped, first you need to tag it with the [AllowGroupBy] attribute (from the namespace: Comarch.POS.Core). This attribute can optionally be used to define the location of the resource file and the postfix of the key with translation. By default, it is Properties.Resources and each key is the property name and the Header postfix. For a property named Name, it will be NameHeader for instance.

Values can also be aggregated only by all properties tagged with the AllowGroupBy attribute. The standard version provides the following aggregation methods: Total, Average, Maximum, Minimum. These methods operate only on properties or numeric or string type, which converts to a numeric type.

Extensibility of aggregation

To add a custom aggregation method, you need to create a new implementation class IAggregationType (namespace: Comarch.WPF.Controls.Aggregation). In this class you need to implement an aggregation mechanism in the Function property.

Assuming that your new aggregation will operate on numbers only, you can make it inherit from the AggregationNumberType class instead of implementing the interface. Then overload the Aggregate method without having to worry about verifying the types of aggregated data.

Finally, register the new class as a new aggregation method in the system. In the Module class, invoke the RegisterDataGridGroupAggregation method, pass the class name and define a key and a resource from which a translation will be retrieved for the new aggregation method.

See the chapter How to implement a custom data aggregation method in a DataGrid in Examples for more details.

How to group by attributes

Grouping and aggregation by attributes works automatically and does not require additional implementation. It is only important that the element object with attributes have the following properties:

  • Attributes property of the dictionary type Dictionary<string,AttributeEntity>
  • AttributeRows property of the AttributesDictionary

Czy ten artykuł był pomocny?