Unplanned
Last Updated: 16 Jul 2026 10:34 by ADMIN
Scheduled for 2026 Q3 (Aug)
Created by: David
Comments: 3
Category: Editor
Type: Feature Request
3

Support multiple users editing the same content in an editor.

This would be similar to the editor in something like confluence or online Word.

Regards

 

Unplanned
Last Updated: 16 Jul 2026 10:29 by ADMIN
Scheduled for 2026 Q3 (Aug)

I'm trying to use the Blazor editor but the "Insert Image" function is very basic. Previously using Webforms & Core the insert image in the editor presented the user with a file management and image upload popup. Is this functionality available with the Blazor component?

 

=====ADMIN EDIT=====

Possible alternative:

  1. Utilize a custom Editor's tool that opens a Window or Dialog containing a FileManager.
  2. Use the FileManager's SelectedItemsChanged event to determine which image the user wants to insert into the Editor.
  3. Programmatically execute the Editor's insertImage command.
Unplanned
Last Updated: 16 Jul 2026 10:29 by ADMIN
Scheduled for 2026 Q3 (Aug)
Created by: Neil N
Comments: 3
Category: DatePicker
Type: Feature Request
18

I would like the following behavior in the date picker. Perhaps it can be achieved with a parameter similar to the one in UI for ASP.NET AJAX - the FocusedDate property (something like RadDatePicker1.FocusedDate = DateTime.Today.AddDays(30);).

The current behaviour is:

* if date is set, show month of set date
*else show month of current date (today)

Desired behaviour:

* if date is set, show month of set date
* else if min date's month is greater than current date month then show month of min date
* else show month of current date

Here is a code snippet to illustrate the issue:

 

Open the picker - it will start in the month with today's date, but I want it to start at the min date - one month later

<TelerikDatePicker @bind-Value="@theDate" Min="@minDate" Max="@maxDate"></TelerikDatePicker>
@code {
    DateTime theDate = DateTime.Now;
    DateTime minDate = DateTime.Now.AddDays(60);
    DateTime maxDate = DateTime.Now.AddDays(230);
}

 

===

ADMIN EDIT

===

The request also applies to the rest of the pickers - DateTimePicker and DateRangePicker.
Unplanned
Last Updated: 16 Jul 2026 07:14 by ADMIN

The NumericTextBox does not render the new Value that is set in ValueChanged if this new value is different than the event argument. Instead, the component clears the textbox, even though the component Value parameter is correct.

https://blazorrepl.telerik.com/wzaAHYas221go9xd48

The problem occurs only if there is an existing value and the user removes it with Backspace.

Need More Info
Last Updated: 16 Jul 2026 06:58 by ADMIN
# Telerik UI for Blazor — TabStrip bug report

Two related defects in `TelerikTabStrip` when the tab headers wrap onto multiple rows.
Filed for GLS (Governance & Legislative System), the resolution submission form
(`/submit-resolution`), which has 12 tabs.

## Environment

- **Telerik UI for Blazor:** v14 (please fill in the exact build number from your
  `LegislationApplications` package reference before submitting)
- **.NET:** 10.0
- **Render mode:** Blazor **Server** (Interactive Server), no WebAssembly
- **Browser:** reproduced in Chromium-based browsers on a wide (≥1200px) window
- **Component config (abridged):**
  ```razor
  <TelerikTabStrip @bind-ActiveTabId="ActiveTabId"
                   PersistTabContent="true"
                   OverflowMode="TabStripOverflowMode.None"   @* wide screens *@
                   ScrollButtonsPosition="TabStripScrollButtonsPosition.Split"
                   ScrollButtonsVisibility="TabStripScrollButtonsVisibility.Auto">
      @* 12 TabStripTabs; several use Visible="@boolExpr" (conditionally shown);
         most use a <HeaderTemplate> that renders the title plus an optional indicator icon *@
  </TelerikTabStrip>
  ```
- On a wide window with `OverflowMode="None"`, the 12 tab headers **wrap onto two rows**
  (row 1 ends at "Budget Impact"; row 2 begins at "OGR Consultation").

---

## Bug 1 — Wrapped tabs: activating a tab at the wrap boundary shows the WRONG content panel

### Repro
1. Open a form whose tab headers wrap to two rows (wide window, `OverflowMode="None"`, enough
   tabs to force a second row).
2. Activate the tab that sits at the **end of the first row** (its immediate left neighbour is on
   the same row; its right neighbour is on the next row). In our form: activate **External
   Documents**, then click **Budget Impact** (last tab on row 1).

### Expected
Budget Impact’s content panel is displayed.

### Actual
- The Budget Impact **header** receives focus/active styling, but the **content area still shows
  the previous tab’s panel** (External Documents).
- It is **deterministic** from the left-neighbour: a 2-second pause before clicking does **not**
  help.
- **Workarounds that do make it switch:** double-clicking the tab, or first activating a tab on a
  **different row** (e.g. OGR Consultation) and then clicking Budget Impact once.

### Proof the server/binding side is correct (it is a client-side rendering defect)
We instrumented the `ActiveTabId` setter and component renders. On the failing single click:
```
ActiveTabId 'tab-submitter'          -> 'tab-external-documents'   (click External)
RENDER  activeTab=tab-external-documents
ActiveTabId 'tab-external-documents' -> 'tab-budget-impact'        (click Budget Impact)
RENDER  activeTab=tab-budget-impact
(no further activity)
```
So `ActiveTabIdChanged` fires with the correct id, `ActiveTabId` becomes `tab-budget-impact`, and
the component re-renders exactly once with the correct active tab — yet the browser keeps showing
the External Documents content panel. The subsequent “rescue” clicks that fix the display produce
**no** server activity at all, confirming the mismatch is purely in the component’s client-side
content-panel switching.

### Confirmed trigger: the wrapping
Forcing the tab headers onto a **single row** with CSS (no other change) makes the bug disappear
entirely — every tab activates its correct panel on the first click:
```css
.k-tabstrip-items-wrapper { flex-wrap: nowrap; overflow-x: auto; }
.k-tabstrip-items         { flex-wrap: nowrap; }
```
This is not an acceptable final fix for us (the product requires the wrapped, all-tabs-visible
layout), but it isolates the cause: **`TelerikTabStrip` mismaps the active content panel when its
headers wrap to more than one row.**

---

## Bug 2 — `OverflowMode="Scroll"` throws an exception for this configuration

### Repro
Set `OverflowMode="TabStripOverflowMode.Scroll"` (instead of `None`) on the same TabStrip
(12 tabs, `PersistTabContent="true"`, several tabs with `Visible="@expr"` including one that is
currently `Visible="false"`, and `<HeaderTemplate>`s).

### Actual
The page throws an unhandled exception on load / render (Blazor error UI). Reverting to
`OverflowMode="None"` removes the exception.

> **To complete this section before filing:** capture the exact exception type, message, and the
> top Telerik stack frames from the browser DevTools console or the app’s server log (Aspire
> dashboard → `legislationwebapp` resource) while `OverflowMode="Scroll"` is active. We suspect it
> relates to scroll-width measurement of a `Visible="false"` tab and/or `HeaderTemplate` tabs, but
> the stack trace will confirm.

---

## Why this matters / requested outcome

- Bug 1 forces a poor workaround (users must double-click or approach tabs from a specific
  direction) or a UX compromise (single-row scrolling instead of the required wrapped layout).
- Bug 2 blocks the natural single-row fix (`OverflowMode="Scroll"`).

We would like `TelerikTabStrip` to either (a) correctly map the active content panel when headers
wrap, or (b) provide a supported single-row/wrapping option that does not throw for this
configuration.
Unplanned
Last Updated: 16 Jul 2026 06:06 by Nicholas
Created by: Nicholas
Comments: 0
Category: UI for Blazor
Type: Feature Request
1

Window, Dialog, and other popups render as children of TelerikRootComponent, which makes CSS Isolation difficult. Current strategy says to use containment selector or global scope css styles.

To allow CSS isolation to pass through, I'd like to see an additional "CssScope" attribute. For example:

<TelerikWindow CssScope="my-custom-scope">
</TelerikWindow>

Then when the window is rendered:

<div ... my-custom-scope>
....
</div>

 

Unplanned
Last Updated: 15 Jul 2026 12:42 by ADMIN
Scheduled for 2026 Q4 (Nov)
Created by: Lee
Comments: 0
Category: Charts
Type: Feature Request
1
Add Chart tooltip positioning capabilities, for example: Top, Right, Bottom, Left.

Due to the lack of an option to specify position, the tooltips  cover part of the line markers, e.g., in a horizontal line Chart scenario. 
Unplanned
Last Updated: 15 Jul 2026 11:27 by ADMIN
Scheduled for 2026 Q3 (Aug)

Bug report

Reproduction of the problem

(bug report only)
Regression introduced in 13.0.0.
1. Run this example: https://blazorrepl.telerik.com/wUuSGClv00orFeRm59

Current behavior

(optional)
The Size, Rounded, FillMode parameters are ignored.

Expected/desired behavior

The parameter values should apply and change the appearance of the SearchBox.

Environment

  • Browser: [all ]
Completed
Last Updated: 15 Jul 2026 10:43 by ADMIN

Hi,

  Using VS code I tried to create a project using the latest Telerik UI for Blazor Productivity tools.  Updated 24-12-03

  The Error:

Completed
Last Updated: 14 Jul 2026 17:30 by ADMIN
Release 2026 14.1.0 (Jul)
Created by: Mikanyg
Comments: 3
Category: RadioGroup
Type: Feature Request
20

I would like to be able to disable one or more radio buttons in the RadioGroup.

=====

TELERIK EDIT

In the meantime, consider the following workaround, which relies on CSS and RadioGroup ItemTemplate.

 

<h4>Default Value Disabled</h4>

RadioGroupValue1: @RadioGroupValue1

<TelerikRadioGroup Data="@Options"
                   @bind-Value="@RadioGroupValue1"
                   ValueField="@nameof(RadioModel.Id)"
                   TextField="@nameof(RadioModel.Text)">
    <ItemTemplate>
        @{
            var dataItem = (RadioModel)context;
            var isChecked = dataItem.Id == RadioGroupValue1;
        }
        @if (!dataItem.Enabled)
        {
            <span class="disabled-radio-option">
                <span class="k-radio-wrap">
                    <input type="radio" value="@dataItem.Id" aria-checked="@isChecked" aria-disabled="true" aria-invalid="true"
                           class="@( $"fake k-radio k-radio-md {(isChecked ? "k-checked" : "")}" )" style="user-select: none;" />
                </span>
                <span>@dataItem.Text</span>
            </span>
        }
        else
        {
            <span>@dataItem.Text</span>
        }
    </ItemTemplate>
</TelerikRadioGroup>

<h4>No Default Value</h4>

RadioGroupValue2: @RadioGroupValue2

<TelerikRadioGroup Data="@Options"
                   @bind-Value="@RadioGroupValue2"
                   ValueField="@nameof(RadioModel.Id)"
                   TextField="@nameof(RadioModel.Text)">
    <ItemTemplate>
        @{
            var dataItem = (RadioModel)context;
            var isChecked = dataItem.Id == RadioGroupValue2;
        }
        @if (!dataItem.Enabled)
        {
            <span class="disabled-radio-option">
                <span class="k-radio-wrap">
                    <input type="radio" value="@dataItem.Id" aria-checked="@isChecked" aria-disabled="true" aria-invalid="true"
                           class="@( $"fake k-radio k-radio-md {(isChecked ? "k-checked" : "")}" )" style="user-select: none;" />
                </span>
                <span>@dataItem.Text</span>
            </span>
        }
        else
        {
            <span>@dataItem.Text</span>
        }
    </ItemTemplate>
</TelerikRadioGroup>

<style>
    .k-radio-list-item:has(.disabled-radio-option) {
        pointer-events: none;
        cursor: default;
        opacity: 0.6;
        gap: 0;
    }

    .disabled-radio-option {
        display: flex;
        align-items: center;
        align-content: center;
        gap: var(--kendo-spacing-1);
    }

    .k-radio-list-item:has(.disabled-radio-option) input:not(.fake) {
        display: none;
    }
</style>

@code{
    private int RadioGroupValue1 { get; set; } = 2;
    private int RadioGroupValue2 { get; set; }

    private List<RadioModel> Options { get; set; } = new List<RadioModel>
    {
        new RadioModel { Id = 1, Text = "Option 1" },
        new RadioModel { Id = 2, Text = "Option 2", Enabled = false },
        new RadioModel { Id = 3, Text = "Option 3" },
        new RadioModel { Id = 4, Text = "Option 4", Enabled = false },
        new RadioModel { Id = 5, Text = "Option 5" },
    };

    public class RadioModel
    {
        public int Id { get; set; }
        public string Text { get; set; } = string.Empty;
        public bool Enabled { get; set; } = true;
    }
}

 

Unplanned
Last Updated: 14 Jul 2026 17:23 by ADMIN
Scheduled for 2026 Q2
So the one thing that is missing for me from the zoom functionality is an event that tells me the selected values

i.e here I would like it to return: 2023/06/11 & 2023/06/18 
In Development
Last Updated: 14 Jul 2026 17:16 by ADMIN
Scheduled for 2026 Q2
Created by: Can
Comments: 1
Category: Notification
Type: Feature Request
13
There could be an event on the component that receives three fields in its event arguments - 1) bool whether it was closed manually or through a timer, 2) the Text (if originally provided) and 3) the model (if provided - you either pass text or a model).
Unplanned
Last Updated: 14 Jul 2026 14:37 by ADMIN
Scheduled for 2026 Q3 (Aug)
Created by: Doug
Comments: 3
Category: DateTimePicker
Type: Feature Request
19

With Blazor server, clicking the NOW button (obviously) sets the time to the time on the server since that's where the code is running. Is there a way to trap the NOW button click or somehow give it an offset or define the value that NOW means so NOW will mean the time that the user is sitting in?

---

TELERIK EDIT

In the meantime, here are a few possible workarounds:

1. Use the DateTimePicker's ValueChanged event to detect new values that are very close or match the server's current DateTime. In such cases, you can assume that the user has clicked on TODAY / NOW, and set the local user time as a component value.

Server Time on UI Refresh: @DateTime.Now.ToLongTimeString()
<br />
User Local Time on Page Load: @LocalTime?.ToLongTimeString()
<br />
User Local Time Offset: @LocalOffset
<br />
<br />

<TelerikDateTimePicker Value="@PickerValue"
                       ValueChanged="@( (DateTime? newValue) => PickerValueChanged(newValue) )"
                       ValueExpression="@( () => LocalTime )"
                       Format="yyyy-MMM-dd HH:mm:ss"
                       Width="240px" />

<!-- Move JS code to a separate JS file in production -->
<script suppress-error="BL9992">
    function getLocalTime() {
        var d = new Date();
        return d.getTimezoneOffset();
    }
</script>

@code {
    private DateTime? PickerValue { get; set; }
    private DateTime? LocalTime { get; set; }
    private int LocalOffset { get; set; }

    private void PickerValueChanged(DateTime? newValue)
    {
        DateTime serverNow = DateTime.Now;
        DateTime utcNow = DateTime.UtcNow;
        TimeSpan nowTolerance = new TimeSpan(0, 0, 10);

        if (newValue - serverNow < nowTolerance)
        {
            PickerValue = utcNow.AddMinutes(-LocalOffset);
        }
        else
        {
            PickerValue = newValue;
        }
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            LocalOffset = await js.InvokeAsync<int>("getLocalTime");
            LocalTime = DateTime.UtcNow.AddMinutes(-LocalOffset);
            StateHasChanged();
        }

        await base.OnAfterRenderAsync(firstRender);
    }
}

 

2. Use the DatePicker's HeaderTemplate with a custom TODAY / NOW button. 

3. Hide the NOW button with CSS:

<style>
    .no-now-button .k-time-now {
        display: none;
    }
</style>

<TelerikDateTimePicker @bind-Value="@PickerValue"
                       Format="yyyy-MMM-dd HH:mm:ss"
                       PopupClass="no-now-button"
                       Width="240px" />

@code {
    private DateTime? PickerValue { get; set; }
}

 

Unplanned
Last Updated: 14 Jul 2026 13:35 by ADMIN
Scheduled for 2026 Q3 (Aug)
Created by: Rick
Comments: 2
Category: Switch
Type: Feature Request
6

I would like to see icon support for the switch control.  See the attached screen shot for the use case.

Unplanned
Last Updated: 14 Jul 2026 11:26 by Wolfgang
Created by: Wolfgang
Comments: 0
Category: Popover
Type: Feature Request
3

Could you include the OnHide event in the TelerikPopover, similar to the Popup component? The Popover already hides on outside clicks, but we have no method to programatically react to it, for example to reset input values and treat it as a cancellation.

===

TELERIK EDIT: In the meantime, a possible workaround is to detect clicks outside the Popover with JavaScript:

https://blazorrepl.telerik.com/QKOBbSbF25rgdsgP20

@implements IAsyncDisposable

@inject IJSRuntime JS

<TelerikPopover @ref="@PopoverRef"
                AnchorSelector=".popover-target"
                ShowOn="@PopoverShowOn.Click"
                Position="@PopoverPosition.Right"
                Offset="20"
                Class="my-popover">
    <PopoverContent>
        Telerik Popover for Blazor
    </PopoverContent>
</TelerikPopover>

<p>Popover Hide Log: @PopoverOnHideLog</p>

<TelerikButton Class="popover-target" OnClick="ShowPopover">
    Show Popover
</TelerikButton>

<script suppress-error="BL9992">
    var dotnetRef;

    window.registerOutsideClick = function (dotnetHelper) {
        dotnetRef = dotnetHelper;
        document.addEventListener("click", onPopoverOutsideClick);
    };

    window.unregisterOutsideClick = function () {
        dotnetRef = null;
        document.removeEventListener("click", onPopoverOutsideClick);
    };

    function onPopoverOutsideClick(e) {
        window.setTimeout(() => {
            const popover = document.querySelector(".my-popover");
            const anchor = document.querySelector(".popover-target");

            const clickedInsidePopover = popover?.contains(e.target);
            const clickedAnchor = anchor?.contains(e.target);

            if (!clickedInsidePopover && !clickedAnchor) {
                dotnetRef?.invokeMethodAsync("OnPopoverHide");
            }
        }, 100);
    }
</script>

@code {
    #nullable enable

    private DotNetObjectReference<__Main>? DotNetRef { get; set; }

    private TelerikPopover? PopoverRef;

    private string PopoverOnHideLog { get; set; } = string.Empty;

    private void ShowPopover()
    {
        PopoverRef?.Show();
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            await JS.InvokeVoidAsync("registerOutsideClick", DotNetRef);
        }
    }

    protected override void OnInitialized()
    {
        DotNetRef = DotNetObjectReference.Create(this);
    }

    [JSInvokable]
    public void OnPopoverHide()
    {
        PopoverOnHideLog = $"Popover closed automatically at {DateTime.Now.ToString("HH:mm:ss")}";

        StateHasChanged();
    }

    public async ValueTask DisposeAsync()
    {
        if (DotNetRef != null)
        {
            DotNetRef.Dispose();
        }

        await JS.InvokeVoidAsync("unregisterOutsideClick");
    }
}

Unplanned
Last Updated: 14 Jul 2026 08:44 by ADMIN
Created by: Hieu
Comments: 0
Category: AutoComplete
Type: Bug Report
8

The AutoComplete component does not update the category grouping header, even when the data within that group has been removed. As a result, the outdated group header remains visible until you scroll down to another group, at which point the first group header refreshes and disappears as expected.

Repro: REPL link.

Completed
Last Updated: 14 Jul 2026 08:44 by ADMIN
Release 2026 14.1.0 (Jul)
Created by: Adam
Comments: 4
Category: Filter
Type: Feature Request
8
We have a large number of fields and it will be useful if we have a search box in the field dropdown to filter them - in a similar fashion to how filtering works in the DropDownList component.
Completed
Last Updated: 14 Jul 2026 08:44 by ADMIN
Release 2026 14.1.0 (Jul)
Created by: Adam
Comments: 1
Category: Grid
Type: Bug Report
1

The Grid performance worsens progressively with each subsequent edit operation. Please optimize that.

Test page: https://blazorrepl.telerik.com/mJuHFNbb17FpJu9b54

Click on a Price or Quantity cell to start edit mode and tab repetitively to observe the degradation.

Completed
Last Updated: 14 Jul 2026 08:44 by ADMIN
Release 2026 14.1.0 (Jul)
Created by: Andre
Comments: 3
Category: Wizard
Type: Feature Request
14

 The disable option is still showing the step and it is not good for me. I have 35 types of transactions and all of them have generic and specific step.

---

ADMIN EDIT

Here is a potential workaround - basic conditional markup can add or remove steps. The key thing is that they will be added to the end of the wizard if they had not been rendered. To handle this, dispose and re-initialize the component, so the step will be rendered at the correct position.

If you have complex steps, you can work around this by creating a collection of descriptor models for the list of steps and create the steps based on that collection, where you can keep the VIsible flag, in a fashion similar to this example for the TabStrip.

<TelerikButton OnClick="@ToggleStep">Toggle attachments step visibility</TelerikButton>

@if (WizardVisible)
{
    <TelerikWizard @bind-Value="@CurrStepIndex">
        <WizardSteps>
            <WizardStep Label="Personal Details" Icon="SvgIcon.User">
                <Content>
                    content here
                </Content>
            </WizardStep>

            @if (AttachmentsStepVisible)
            {
                <WizardStep Label="Attachments" Icon="SvgIcon.Paperclip">
                    <Content>
                        conditional content here
                    </Content>
                </WizardStep>
            }

            <WizardStep Label="Confirmation" Icon="SvgIcon.Check">
                <Content>
                    other content here
                </Content>
            </WizardStep>
        </WizardSteps>
    </TelerikWizard>
}


@code {
    private bool AttachmentsStepVisible { get; set; }
    private bool WizardVisible { get; set; } = true;

    private int CurrStepIndex { get; set; }

    private async void ToggleStep()
    {
        //dispose the Wizard
        WizardVisible = false;

        // defence against hiding the step when it is the last step, which would cause an exception
        if (AttachmentsStepVisible && CurrStepIndex == 2)
        {
            CurrStepIndex = 1;
        }

        //the actual visibility toggle
        AttachmentsStepVisible = !AttachmentsStepVisible;

        //allow some time for the disposal and toggling the step visibility prior to re-initialization
        await Task.Delay(10);

        //re-initialize the Wizard
        WizardVisible = true;

        StateHasChanged();
    }
}

---

Completed
Last Updated: 14 Jul 2026 08:44 by ADMIN
Release 2026 14.1.0 (Jul)

The CheckBoxList filter does not work as expected when the Grid is bound to ExpandoObject

===

ADMIN EDIT: A possible workaround is to bind the Grid with OnRead event and populate the MemberType property of the filter descriptors manually:

@using System.Dynamic
@using Telerik.DataSource
@using Telerik.DataSource.Extensions

<TelerikGrid OnRead="@OnGridRead"
             TItem="@ExpandoObject"
             Pageable="true"
             Sortable="true"
             FilterMode="@GridFilterMode.FilterMenu"
             FilterMenuType="@FilterMenuType.CheckBoxList"
             Height="400px">
    <GridToolBarTemplate>
        <GridSearchBox />
    </GridToolBarTemplate>
    <GridColumns>
        @{
            if (GridData != null && GridData.Any())
            {
                <GridColumn Field="PropertyInt" FieldType="@GridPropertyTypes["PropertyInt"]" />
                <GridColumn Field="PropertyString" FieldType="@GridPropertyTypes["PropertyString"]" />
                <GridColumn Field="PropertyGroup" FieldType="@GridPropertyTypes["PropertyString"]" />
                <GridColumn Field="PropertyDate" FieldType="@GridPropertyTypes["PropertyDate"]" />
                <GridColumn Field="PropertyBool" FieldType="@GridPropertyTypes["PropertyBool"]" />
            }
        }
    </GridColumns>
</TelerikGrid>

@code {
    private List<ExpandoObject> GridData { get; set; } = new List<ExpandoObject>();

    private Dictionary<string, Type> GridPropertyTypes { get; set; } = new Dictionary<string, Type>() {
        { "Id", typeof(int) },
        { "PropertyInt", typeof(int) },
        { "PropertyString", typeof(string) },
        { "PropertyGroup", typeof(string) },
        { "PropertyDate", typeof(DateTime) },
        { "PropertyBool", typeof(bool) }
    };

    private async Task OnGridRead(GridReadEventArgs args)
    {
        args.Request.Filters.OfType<CompositeFilterDescriptor>()
        .Each(x =>
        {
            x.FilterDescriptors.OfType<FilterDescriptor>()
                .Each(y => y.MemberType = GridPropertyTypes[y.Member]);
        });

        var result = GridData.ToDataSourceResult(args.Request);

        args.Data = result.Data;
        args.Total = result.Total;
        args.AggregateResults = result.AggregateResults;
    }

    protected override void OnInitialized()
    {
        for (int i = 1; i <= 18; i++)
        {
            dynamic expando = new ExpandoObject();

            expando.Id = i;
            expando.PropertyGroup = $"Group {(i % 3 + 1)}";
            expando.PropertyInt = i;
            expando.PropertyString = $"String {(char)(64 + i)}{(char)(64 + i)}";
            expando.PropertyDate = DateTime.Now.AddMonths(-i);
            expando.PropertyBool = i % 2 != 0;

            GridData.Add(expando);
        }
    }
}

1 2 3 4 5 6