private async Task <IEnumerable <TItem> > GetDataAsync(string?key = null)
        {
            if (DataProvider is null)
            {
                return(new TItem[0]);
            }
            try
            {
                BlockOverlayService.Show();
                var request = new DataRequest <TItem>
                {
                    Skip        = 0,
                    ForceUpdate = false,
                    // if load on demand and item key is given then only fetch immediate child items
                    SearchText = LoadOnDemand ? key ?? string.Empty : null
                };

                // perform query data
                var response = await DataProvider
                               .GetDataAsync(request, CancellationToken.None)
                               .ConfigureAwait(true);

                // allow calling application to filter/add items etc
                var items = new List <TItem>(response.Items);
                await ItemsLoaded.InvokeAsync(items).ConfigureAwait(true);

                return(items);
            }
            finally
            {
                BlockOverlayService.Hide();
            }
        }
        /// <summary>
        /// Requests data from the data provider using the current settings.
        /// </summary>
        /// <param name="searchText">Optional override for the search text.</param>
        protected async Task GetDataAsync(string?searchText = null)
        {
            try
            {
                BlockOverlayService.Show();

                //var sortColumn = Columns.SingleOrDefault(c => c.SortColumn);
                var sortColumn = Columns.Find(x => x.Id == SortCriteria?.Key || x.Title == SortCriteria?.Key);
                var request    = new DataRequest <TItem>
                {
                    Skip                = 0,
                    ForceUpdate         = false,
                    SortFieldExpression = sortColumn?.Field,
                    SortDirection       = sortColumn?.SortDirection,
                    SearchText          = searchText ?? SearchText
                };

                // paging
                if (PageCriteria != null)
                {
                    request.Take = (int)PageCriteria.PageSize;
                    request.Skip = (int)PageCriteria.PreviousItems;
                }

                // perform query data
                var response = await DataProvider
                               .GetDataAsync(request, CancellationToken.None)
                               .ConfigureAwait(true);

                // allow calling application to filter/add items etc
                var items = new List <TItem>(response.Items);
                ItemsLoaded?.Invoke(items);                 // must use an action here and not an EventCallaback as that leads to infinite loop and 100% CPU
                ItemsToDisplay = items;

                // update pager state
                if (PageCriteria != null)
                {
                    PageCriteria.TotalCount = (uint)(response.TotalCount ?? 0);
                }

                // clear selection
                await ClearSelectionAsync().ConfigureAwait(true);
            }
            finally
            {
                BlockOverlayService.Hide();
            }
        }