Completed
Last Updated: 12 Jan 2026 19:48 by ADMIN
The bottom border of the tabstrip item is not hidden as expected when the component is hosted in a Modal window.
Completed
Last Updated: 09 Jan 2026 13:56 by ADMIN
Created by: Winston
Comments: 2
Category: TreeView
Type: Bug Report
2

There are two related issues in this bug report:

  1. TreeView does not allow horizontally scrolling when there are items that extend past the viewport
  2. TreeView cuts off items when the browser is zoomed in

See REPL: https://blazorrepl.telerik.com/wwOHGPvi11wy1OBp06

Steps to reproduce:

  1. Open and run the REPL.
  2. Observe that the last deeply-nested tree item, Design20.......01 is not fully visible (if it is fully visible, just add more 0s in the middle). Specifically, the trailing "1" is not visible and cannot be scrolled to.
  3. Zoom the browser to 200%.
  4. Observe that the TreeView still does not allow horizontal scrolling to view any of the items cut off by the increased zoom.
Completed
Last Updated: 07 Jan 2026 09:34 by ADMIN

When you type the time in the time picker, it changes the date to the current date, while it should change only the time portion.

---

ADMIN EDIT

A workaround is to use the original year, month and date portions of the view-model field and capture the time portion from the ValueChanged event:

@selectedTime?.ToString("F")

<TelerikTimePicker Min="@Min" Max="@Max" Format="hh:mm:ss tt" 
                   Value="@selectedTime" ValueChanged="@( (DateTime? v) => ValueChangedHandler(v) )">
</TelerikTimePicker>

@code {
    public DateTime Min = new DateTime(1900, 1, 1, 10, 0, 0);
    public DateTime Max = new DateTime(1900, 1, 1, 20, 0, 0);
    public DateTime? selectedTime { get; set; } = new DateTime(1900, 1, 1, 12, 0, 0);

    void ValueChangedHandler(DateTime? updatedTime)
    {
        selectedTime = new DateTime(
                selectedTime.Value.Year,
                selectedTime.Value.Month,
                selectedTime.Value.Day,
                updatedTime.Value.Hour,
                updatedTime.Value.Minute,
                updatedTime.Value.Second
            );
    }
}

---

Completed
Last Updated: 06 Jan 2026 14:31 by ADMIN
Created by: Isaac
Comments: 1
Category: UI for Blazor
Type: Feature Request
1

Image Collection Viewer / Selector Component

A flexible and accessible image viewer / selector for Blazor applications, similar to what popular eCommerce websites use to show products.

    Features

    • Accessibility: Uses ARIA roles and labels for screen reader support and keyboard navigation.
    • Configurable Layout: Supports custom Height and Width parameters to fit various UI needs.
    • Aspect Ratio ControlConstrainImageHeight and ConstrainImageWidth parameters allow precise control over aspect ratio, whether to maintain aspect ratio and/or constrain height and width.
    • ImageInfo Model: Accepts a collection of ImageInfo objects, each with a required image source and optional alt text for accessibility.
    • Alt Text Support: Ensures all images have descriptive alt text for improved accessibility.
    • Scrollbar Handling: Automatically displays a vertical scrollbar if the image list exceeds the constrained height, ensuring all images remain accessible.
    • Visual Feedback: Selected and focused images are visually highlighted for clear user interaction.

    Sample Code

    ImageCollectionViewer.razor

    @inject ITelerikStringLocalizer Loc
    
    <LanguageTrackProvider OnInitializeEvent="provider => provider.RegisterComponent(this)" />
    
    @if (Images.Any() && _selectedImage != null)
    {
        <div class="d-flex @Class" style="height: @Height; width: @Width;">
            <ul aria-label="@Loc["ImageThumbnails"]" role="radiogroup" class="image-collection-button-container">
                @foreach (var image in Images)
                {
                    <li>
                        <button @onclick="() => OnImageSelect(image)"
                                class="@($"image-collection-button{(image.Src == _selectedImage.Src ? " selected" : "")}")"
                                role="radio" aria-checked="@(image.Src == _selectedImage.Src ? "true" : "false")">
                            <img src="@image.Src" alt="@image.Alt" />
                        </button>
                    </li>
    
                }
            </ul>
            <div class="image-collection-image-container">
                <MagnifiableImage Image="@(new ImageInfo(_selectedImage.Src, _selectedImage.Alt))" Class="image-collection-image" MagnifyScale="@MagnifyScale"
                                  Height="@(ConstrainImageHeight ? "calc(100% - 2px)" : "auto")" Width="@(ConstrainImageWidth ? "100%" : "auto")" />
            </div>
        </div>
    }
    else
    {
        <TelerikSkeleton ShapeType="@SkeletonShapeType.Rectangle" Height="@Height" Width="@Width" Class="@Class"/>
    }
    
    <style>
        .image-collection-button-container {
            flex: 0 0 auto;
            width: 10%;
            height: 100%; 
            min-width: 90px;
            max-width: 110px;
            overflow-y: auto;
            padding: 2px;
            margin: 0;
            scrollbar-color: rgba(1, 1, 1, 0.25) rgba(0, 0, 0, 0);
            scrollbar-gutter: stable;
            list-style: none;
        }
        
        .image-collection-button {
            padding: 0;
            margin-bottom: 1rem;
            border: 1px solid var(--kendo-color-border, rgba(0, 0, 0, 0.08));
            border-radius: 0.5rem;
            width: auto;
            aspect-ratio: 1 / 1;
            display: block;
        }
        .image-collection-button:hover {
            filter: brightness(90%);
        }
        .image-collection-button:focus {
            outline: none;
            box-shadow: 0 0 0 2px color-mix(in srgb, var(--kendo-color-on-app-surface, #424242) 50%, transparent);
        }
        .image-collection-button.selected {
            box-shadow: 0 0 0 2px var(--kendo-color-primary, #1274AC);
        }
        .image-collection-button img {
            width: 100%;
            height: 100%;
            min-width: 70px;
            min-height: 70px;
            max-width: 90px;
            max-height: 90px;
            object-fit: cover;
            border-radius: 0.5rem;
            display: block;
        }
        
        .image-collection-image-container {
            flex: 0 0 auto;
            width: 90%;
            padding: 2px;
        }
        
        .image-collection-image {
            border: 1px solid var(--kendo-color-border, rgba(0, 0, 0, 0.08));
        }
    </style>

    ImageCollectionViewer.razor.cs

    using Microsoft.AspNetCore.Components;
    using Telerik.Blazor.Components;
    
    namespace RazorLibrary.Components.Images;
    
    /// <summary>
    /// <para>
    /// Displays a collection of selectable image thumbnails provided by <see cref="Images"/> and a main image display area.
    /// If <see cref="Images"/> is empty, displays a <see cref="TelerikSkeleton"/> placeholder instead. Supports
    /// accessibility, configurable height via <see cref="Height"/>, width via <see cref="Width"/>, aspect ratio control
    /// via <see cref="ConstrainImageHeight"/> and <see cref="ConstrainImageWidth"/>, and alt text for images.
    /// </para>
    /// <para>
    /// Usage: 
    /// <code>
    /// @using RazorLibrary.Components.Images
    ///
    /// 
    /// &lt;ImageCollection Images="myImages" Height="300px" Width="100%" /&gt;
    ///
    /// 
    /// @code {
    ///     private List&lt;ImageInfo&gt; myImages = new()
    ///     {
    ///         new ImageInfo("img1.jpg", "First image"),
    ///         new ImageInfo("img2.jpg", "Second image")
    ///     };
    /// }
    /// </code>
    /// </para>
    /// </summary>
    public partial class ImageCollection
    {
        /// <summary>
        /// The collection of images to display in the image collection.
        /// </summary>
        [Parameter] public IEnumerable<ImageInfo> Images { get; set; } = [];
    
        /// <summary>
        /// The overall height of the image collection component (e.g., "200px", "100%", or "auto"). Default is "auto".
        /// </summary>
        [Parameter] public string Height { get; set; } = "auto";
        /// <summary>
        /// The overall width of the image collection component (e.g., "200px", "100%", or "auto"). Default is "auto".
        /// </summary>
        [Parameter] public string Width { get; set; } = "auto";
    
        /// <summary>
        /// If true, sets the main image display height to 100%, which constrains it to the value specified by <c>Height</c>.
        /// If false, height is auto. Maintains aspect ratio unless both <c>FixImageHeight</c> and <c>FixImageWidth</c> are true.
        /// Default is false.
        /// </summary>
        [Parameter] public bool ConstrainImageHeight { get; set; } = false;
        /// <summary>
        /// If true, sets the main image display width to 100%, which constrains it to the value specified by <c>Width</c>.
        /// If false, width is auto. Maintains aspect ratio unless both <c>FixImageHeight</c> and <c>FixImageWidth</c> are true.
        /// Default is true.
        /// </summary>
        [Parameter] public bool ConstrainImageWidth { get; set; } = true;
    
        /// <summary>
        /// The magnification scale for the magnifier. Default is 3 (3x magnification).
        /// </summary>
        [Parameter] 
        public double MagnifyScale { get; set; } = 3;
        
        /// <summary>
        /// Applies additional CSS classes to the ImageCollection's root element for custom styling and visual modifications.
        /// </summary>
        [Parameter] public string Class { get; set; } = string.Empty;
    
        private ImageInfo? _selectedImage;
    
        /// <inheritdoc />
        protected override void OnInitialized()
        {
            _selectedImage = Images.FirstOrDefault();
        }
    
        private void OnImageSelect(ImageInfo imageInfo)
        {
            _selectedImage = imageInfo;
        }
    }

    ImageInfo.cs

    namespace RazorLibrary.Components.Images;
    
    /// <summary>
    /// Information about an image, including the source URL and alt text.
    /// </summary>
    /// <param name="Src">The image source URL. Required.</param>
    /// <param name="Alt">The image alt text. Optional.</param>
    public record ImageInfo(string Src, string? Alt = null);

    Note

    The sample code uses the MagnifiableImage component, which is another feature request. The MagnifiableImage component can be replaced with a img element.


    Completed
    Last Updated: 06 Jan 2026 13:20 by ADMIN
    Release 2026 Q1 (Feb)

    I produced this REPL: https://blazorrepl.telerik.com/QJbcvsFJ43Oc231U28

    By clicking the Close X button on each DatePicker, the result shows the invalid state when the DatePicker uses a PlaceHolder.

    I would like clarification on why this may be happening.

    Or perhaps it is a bug.

    Christopher Taleck

    Completed
    Last Updated: 06 Jan 2026 13:19 by ADMIN
    Release 2026 Q1 (Feb)

    Description

    The DatePicker and the rest of the picker that have the ShowClearButton parameter (e.g., TimePicker, DateTimePicker) do not hide the clear button, when the initial value is null or after the user clears the existing value. This is inconsistent with the TextBox behavior, or with the behavior of the pickers in other suites.

    Workaround
    https://blazorrepl.telerik.com/wpaiFzFc26Zot90s18

    Steps To Reproduce

    Run the following REPL example: https://blazorrepl.telerik.com/QfEWvzvc35O5poYW04

    Actual Behavior

    The clear button is visible.

    If you select a date and clear it, the clear button remains visible.

    Expected Behavior

    The clear button is hidden.

    Browser

    All

    Last working version of Telerik UI for Blazor (if regression)

    No response

    Completed
    Last Updated: 05 Jan 2026 14:38 by ADMIN
    Created by: Lukas
    Comments: 4
    Category: Grid
    Type: Bug Report
    0

    On the bright side, I don't have to write a repro code sample for this issue since this is present in the example on https://www.telerik.com/blazor-ui/documentation/components/grid/templates/popup-form-template#example

    1. Open the edit popup for any item and close the window with the "x" in the top right
    2. Now click the button to add a new item

    The popup for adding a new item now shows the values of the previously edited item. The same goes for editing any other item. As long as the popup is closed with the "x" in the top right, the edit context remains.

    The Problem relates to the ExitGridEditMode method and when it is and isn't called. Specifically, it is not called when the edit popup is closed with the close button in the top right of the window. I have also not found any way to get notified about the edit popup being closed with the close button. The Grid contains a hard-coded <TelerikWindow> and there doesn't appear to be a way to influence this window action or any events that it triggers.

    Completed
    Last Updated: 17 Dec 2025 09:18 by ADMIN
    Release 2026 Q1 (Feb)
    Created by: Taarti
    Comments: 4
    Category: Grid
    Type: Bug Report
    28

    In the case of a sorted column, NVDA is not narrating the correct column name and narrating the incorrect Roles for the column headers.

    In the case of an unsorted column, NVDA is narrating the column name twice and repeating the information.

    Completed
    Last Updated: 11 Dec 2025 15:29 by ADMIN
    Release 2026 Q1 (Feb)
    Created by: Jerome
    Comments: 1
    Category: DockManager
    Type: Bug Report
    2

    Description

    A pane that has Closeable="false" set does not render a "close" button and should not be closeable through any user interaction. However, pressing the Esc keyboard key (while the pane is floating and has the focus) closes the pane.

    Steps To Reproduce

    Run the following REPL example: https://blazorrepl.telerik.com/QTkgmKuM23c0uPv125

    1. Focus the floating pane.
    2. Press the Esc keyboard key.

    A slightly different scenario: there are no panes declared in a DockManagerFloatingPanes tag. The user drags a DockManagerContentPane making it float, then presses Esc key: https://blazorrepl.telerik.com/QJuUGUlv43toAJhk40

    Actual Behavior

    The floating pane closes.

    Expected Behavior

    The floating pane remains open.

    Workaround:
    Add the following script to the view:

    <script suppress-error="BL9992">
        document.addEventListener(
          "keydown",
          function (e) {
            if (e.key === "Escape" && e.target.classList.contains("k-dock-manager-window")) {
              e.stopImmediatePropagation();
              e.preventDefault();
            }
          },
          true
        );
    </script>

    Browser

    All

    Last working version of Telerik UI for Blazor (if regression)

    No response

    Completed
    Last Updated: 11 Dec 2025 11:57 by ADMIN
    Release 2026 Q1 (Feb)

    I am creating a Donut Chart and believe I have found a bug. On the initial load of the page, the donut chart element is not playing its animation when the label property "Visible=false". Instead, it pops on with no animation. The animations do play on the drilldown elements on their initial loads, but clicking the refresh chart button also causes this behavior even on drilldown levels. Resetting the drilldown also causes this behavior. The chart legend remains visible during the time when the chart is not. Setting the labels visible property to true causes the animations to play correctly. This proof of concept utilizes static data. The application was created using the telerik templates and is correctly injecting the telerik components as all other telerik components, including other chart components, are functioning as expected. I have isolated the code for the donut chart and posted it here.

     

    <TelerikButton OnClick="@(() => DonutChart.Refresh())">Refresh Donut Chart</TelerikButton>
    <TelerikButton OnClick="@(() => DonutChart.ResetDrilldownLevel(0))">Reset DrillDown</TelerikButton>
    <!-- Donut Chart -->
    <TelerikChart @ref="DonutChart">
        <ChartTitle Text="Donut Chart" />
        <ChartLegend Position="Telerik.Blazor.ChartLegendPosition.Right" />
        <ChartSeriesItems>
            <ChartSeries Type="ChartSeriesType.Donut"
            Data="@donutData"
            Field="@nameof(DonutModel.Number)"
            CategoryField="@nameof(DonutModel.Category)"
            ColorField="@nameof(DonutModel.SegmentColor)"
            DrilldownField="@nameof(DonutModel.DrillDown)">
                <ChartSeriesBorder Color="white" Width="2" />
                <ChartSeriesLabels Position="ChartSeriesLabelsPosition.Above"
                Visible="false"
                Background="transparent">
                </ChartSeriesLabels>
            </ChartSeries>
        </ChartSeriesItems>
    </TelerikChart>

    @code {
        // Donut Chart
        public TelerikChart DonutChart;

        public class DonutModel
        {
            public string Category { get; set; }
            public int Number { get; set; }
            public string SegmentColor { get; set; }
            public ChartSeriesDescriptor? DrillDown { get; set; }
        }

        public List<DonutModel> donutData = new List<DonutModel>
        {
            new DonutModel
            {
                Category = "Category 1 with Drilldown",
                Number = 263,
                SegmentColor = "#9d3cc7",
                DrillDown = new ChartSeriesDescriptor
                {
                    Name = "Drilldowns",
                    Type = ChartSeriesType.Donut,
                    Field = nameof(DonutModel.Number),
                    CategoryField = nameof(DonutModel.Category),
                    DrilldownField = nameof(DonutModel.DrillDown),
                    Data = new List<DonutModel>()
                    {
                        new DonutModel
                        {
                            Category = "Drill Down 1",
                            Number = 102,
                            SegmentColor = "#9d3cc7",
                            DrillDown = new ChartSeriesDescriptor
                            {
                                Name = "People",
                                Type = ChartSeriesType.Donut,
                                Field = nameof(DonutModel.Number),
                                CategoryField = nameof(DonutModel.Category),
                                Data = new List<DonutModel>()
                                {
                                    new DonutModel
                                    {
                                        Category = "John Doe",
                                        Number = 27,
                                        SegmentColor = "#9d3cc7"
                                    },
                                    new DonutModel
                                    {
                                        Category = "David Smith",
                                        Number = 45,
                                        SegmentColor = "green"
                                    },
                                    new DonutModel
                                    {
                                        Category = "Mary Johnson",
                                        Number = 63,
                                        SegmentColor = "yellow"
                                    },
                                    new DonutModel
                                    {
                                        Category = "Robert Brown",
                                        Number = 56,
                                        SegmentColor = "orange"
                                    }
                                }
                            }
                        },
                        new DonutModel
                        {
                            Category = "Drilldown 2",
                            Number = 67,
                            SegmentColor = "green",
                            DrillDown = new ChartSeriesDescriptor
                            {
                                Name = "People",
                                Type = ChartSeriesType.Donut,
                                Field = nameof(DonutModel.Number),
                                CategoryField = nameof(DonutModel.Category),
                                Data = new List<DonutModel>()
                                {
                                    new DonutModel
                                    {
                                        Category = "John Doe",
                                        Number = 15,
                                        SegmentColor = "#9d3cc7"
                                    },
                                    new DonutModel
                                    {
                                        Category = "David Smith",
                                        Number = 17,
                                        SegmentColor = "green"
                                    },
                                    new DonutModel
                                    {
                                        Category = "Mary Johnson",
                                        Number = 19,
                                        SegmentColor = "yellow"
                                    },
                                    new DonutModel
                                    {
                                        Category = "Robert Brown",
                                        Number = 16,
                                        SegmentColor = "orange"
                                    }
                                }
                            }
                        },
                        new DonutModel
                        {
                            Category = "Drilldown 3",
                            Number = 10,
                            SegmentColor = "orange",
                            DrillDown = new ChartSeriesDescriptor
                            {
                                Name = "People",
                                Type = ChartSeriesType.Donut,
                                Field = nameof(DonutModel.Number),
                                CategoryField = nameof(DonutModel.Category),
                                Data = new List<DonutModel>()
                                {
                                    new DonutModel
                                    {
                                        Category = "John Doe",
                                        Number = 3,
                                        SegmentColor = "#9d3cc7"
                                    },
                                    new DonutModel
                                    {
                                        Category = "David Smith",
                                        Number = 4,
                                        SegmentColor = "green"
                                    },
                                    new DonutModel
                                    {
                                        Category = "Mary Johnson",
                                        Number = 1,
                                        SegmentColor = "yellow"
                                    },
                                    new DonutModel
                                    {
                                        Category = "Robert Brown",
                                        Number = 2,
                                        SegmentColor = "orange"
                                    }
                                }
                            }
                        }
                    }
                }
            },
            new DonutModel
            {
                Category = "Category 2 with no Drilldown",
                Number = 31,
                SegmentColor = "#fab933"
            }
        };
    Completed
    Last Updated: 05 Dec 2025 11:58 by ADMIN
    Release 2026 Q1 (Feb)

    Description

    Regression introduced in v9.0.0.

    Initial binding to a property works, but when either the RemoveAttributes or the StripTags parameter is set, on changing the Editor value, two-way binding does not work and the new Editor value is not reflected in the property value.

    Potentially related to #3887

    Steps To Reproduce

    1. Run the following example:
    <p role="status">Current Editor value: @CurrentEditorText</p>
    
    <TelerikEditor @bind-Value="@CurrentEditorText">
        <EditorSettings>
            <EditorPasteSettings ConvertMsLists="@true"
                                 RemoveAllAttributes="@true"
                                 RemoveAttributes="@(new List<string> { "lang" })"
                                 RemoveHtmlComments="@true"
                                 RemoveMsClasses="@true"
                                 RemoveMsStyles="@true"
                                 StripTags="@( new List<string> { "h1" })">
            </EditorPasteSettings>
        </EditorSettings>
    </TelerikEditor>
    
    
    @code {
        private string CurrentEditorText { get; set; } = @"<strong>initial</strong><span>value</span>";
    
        public List<string> RemoveAttributes { get; set; } = new List<string>() { "data-id" };
    
        public List<string> StripTags { get; set; } = new List<string>() { "font" };
    }
    
    1. Type in the Editor's content area

    Actual Behavior

    The CurrentEditorText property value is not updated.

    Expected Behavior

    The CurrentEditorText property value is updated.

    Browser

    All

    Last working version of Telerik UI for Blazor (if regression)

    8.1.1

    Completed
    Last Updated: 05 Dec 2025 08:35 by ADMIN

    ---

    ADMIN EDIT

    A workaround is to initialize the RemoveAttributes list:

    <TelerikEditor @bind-Value="@EditorContent">
        <EditorSettings>
            <EditorPasteSettings 
                                 RemoveAttributes="@( new List<string>() )"
                                >
            </EditorPasteSettings>
        </EditorSettings>
    </TelerikEditor>
    
    @EditorContent
    
    @code{
        string EditorContent { get; set; }
    }

    ---

    Completed
    Last Updated: 24 Nov 2025 15:42 by ADMIN
    Release 12.0.0
    The WindowAction's OnClick event handler is not firing if the project target framework is .NET10.
    Completed
    Last Updated: 17 Nov 2025 09:14 by ADMIN
    Release 2026 Q1 (Feb)
    Created by: Craig
    Comments: 1
    Category: Chat
    Type: Bug Report
    1

    Hi,

    When submitting a chat message using the Chat component, it is possible to lose recently entered text.

    I believe this is because:

    1. The TextArea in the Chat component has a debounce delay (the default 150ms delay)
    2. Pressing enter (or clicking the send button) fires the SendMessageAsync method instantly
    3. SendMessageAsync uses the last text received from the TextArea, but this can be up to 150ms behind due to the debounce delay

    This is reproducible on the Chat component documentation page, https://www.telerik.com/blazor-ui/documentation/components/chat/overview#creating-blazor-chat:

    1. Type in some text
    2. Wait 150ms (i.e., wait for the button to enable, otherwise the enter keypress and button clicks are ignored)
    3. Type some more text and quickly hit enter (or press the button)

    Depending on the timing, the last few characters/words will be lost and not included in the message.

    I encounter this issue in version 11 with server side rendering, but the documentation page appears to be using version 12 with web assembly.

    Thanks,

    Craig

     

    Completed
    Last Updated: 17 Nov 2025 07:24 by ADMIN
    Created by: Jamie
    Comments: 4
    Category: UI for Blazor
    Type: Bug Report
    0

    After upgrading to 12.0.0, the Content does not change when clicking tabs. I always see the Content of the first tab.

    My project targets .net8.

    Completed
    Last Updated: 12 Nov 2025 10:58 by ADMIN
    Release 12.0.0
    Created by: Bernd
    Comments: 0
    Category: Charts
    Type: Feature Request
    3

    Currently the bubble sizes in the Chart are determined automatically, according to an internal algorithm.

    Please add parameters for setting specific min and max bubble sizes by the application.

    Completed
    Last Updated: 12 Nov 2025 10:58 by ADMIN
    Release 12.0.0
    Created by: Jason
    Comments: 0
    Category: DropDownButton
    Type: Bug Report
    1

    When using the OnClick event on a DropDownButtonItem, the MouseEventArgs parameter is always null. However, if the OnClick event is used on the main TelerikDropDownButton component, the MouseEventArgs works correctly.

    REPL reproduction - https://blazorrepl.telerik.com/mfYdbbPQ37jhZlMq47

    Completed
    Last Updated: 12 Nov 2025 10:58 by ADMIN
    Release 12.0.0

    We are experiencing an issue where the ExportToPdfAsync() method on TelerikGrid is returning Excel data (XLSX format) instead of PDF data. This is causing MIME type errors when trying to process the exported data as a PDF.

     

    ===ADMIN EDIT===

    Workaround

    In the meantime, a possible workaround would be to use the document processing library (make sure the correct packages are installed for it) and import the xlsx file to a workbook, and then export the workbook to PDF. Here is an improvised example that demonstrates this by saving the file in your wwwroot folder as a pdf.

    @inject IWebHostEnvironment HostingEnvironment
    
    <TelerikGrid Data="@bookList" Height="75svh" Resizable="true" Sortable="true" Pageable="true" PageSize="15"
                 FilterMode="@GridFilterMode.FilterMenu" SelectionMode="@GridSelectionMode.Multiple"
                 SelectedItems="@SelectedBooks" @ref="@BookGrid"
                 SelectedItemsChanged="@((IEnumerable<BookInfo> sel) => OnRowSelect(sel))">
        <GridToolBarTemplate>
            <TelerikButton OnClick="@GenerateReport">Generate PDF</TelerikButton>
        </GridToolBarTemplate>
        <GridExport>
            <GridPdfExport AllPages="true" PageOrientation="GridPdfExportPageOrientation.Landscape"
                           PaperSize="GridPdfExportPaperSize.A3" />
        </GridExport>
        <GridColumns>
            <GridCheckboxColumn CheckBoxOnlySelection="true"></GridCheckboxColumn>
            <GridColumn Field="ISBN">
                <HeaderTemplate><b>ISBN</b></HeaderTemplate>
            </GridColumn>
            <GridColumn Field="Author">
                <HeaderTemplate><b>Author</b></HeaderTemplate>
            </GridColumn>
            <GridColumn Field="Title">
                <HeaderTemplate><b>Title</b></HeaderTemplate>
            </GridColumn>
            <GridColumn Field="Genre">
                <HeaderTemplate><b>Genre</b></HeaderTemplate>
            </GridColumn>
            <GridColumn Field="PublishedYear">
                <HeaderTemplate><b>Year</b></HeaderTemplate>
            </GridColumn>
            <GridColumn Field="CopiesAvailable">
                <HeaderTemplate><b>Copies</b></HeaderTemplate>
            </GridColumn>
        </GridColumns>
    </TelerikGrid>
    
    @code {
        private async Task GenerateReport()
        {
            isLoading = true;
            var pdfStream = await BookGrid.ExportToPdfAsync();
    
            // The stream is actually XLSX, so convert it to PDF
            using var ms = new MemoryStream(pdfStream.ToArray());
    
            var xlsxProvider = new Telerik.Windows.Documents.Spreadsheet.FormatProviders.OpenXml.Xlsx.XlsxFormatProvider();
            var workbook = xlsxProvider.Import(ms);
    
            var rootPath = HostingEnvironment.WebRootPath;
            var saveLocation = Path.Combine(rootPath, "LibraryBooks.pdf");
            var pdfProvider = new Telerik.Windows.Documents.Spreadsheet.FormatProviders.Pdf.PdfFormatProvider();
            using (var fileStream = new FileStream(saveLocation, FileMode.Create))
            {
                pdfProvider.Export(workbook, fileStream);
            }
        }
    
        public class BookInfo
        {
            public string ISBN { get; set; }
            public string Author { get; set; }
            public string Title { get; set; }
            public string Genre { get; set; }
            public int PublishedYear { get; set; }
            public int CopiesAvailable { get; set; }
        }
    
        private List<BookInfo> bookList = new()
        {
            new BookInfo { ISBN = "978-0451524935", Author = "George Orwell", Title = "1984", Genre = "Dystopian", PublishedYear = 1949, CopiesAvailable = 4 },
            new BookInfo { ISBN = "978-0439139601", Author = "J.K. Rowling", Title = "Harry Potter and the Goblet of Fire", Genre = "Fantasy", PublishedYear = 2000, CopiesAvailable = 7 },
            new BookInfo { ISBN = "978-0140449266", Author = "Homer", Title = "The Odyssey", Genre = "Epic Poetry", PublishedYear = -800, CopiesAvailable = 2 }
        };
    
        private TelerikGrid<BookInfo> BookGrid;
        private List<BookInfo> SelectedBooks = new();
        private bool isLoading = false;
    
        private void OnRowSelect(IEnumerable<BookInfo> selected)
        {
            SelectedBooks = selected.ToList();
        }
    }

     

    Completed
    Last Updated: 12 Nov 2025 10:58 by ADMIN
    Release 12.0.0
    Created by: Plastic
    Comments: 6
    Category: Grid
    Type: Bug Report
    1
    A Grid component with a ColumnMenu increases memory usage due to event handler leaks specifically associated with the ColumnMenu.
    Completed
    Last Updated: 12 Nov 2025 10:58 by ADMIN
    Release 12.0.0
    Created by: Rami
    Comments: 1
    Category: MultiSelect
    Type: Bug Report
    1

    I was hoping to use the new AllowCustom feature to let users name a few areas, save those names in the backend and later show them as preselected when the user comes back so they don't have to retype the names every time they do an operation. But alas, the AllowCustom seems to only allow preselecting from what's in the Data list of values.

    So code like below doesn't actually show a chip for Rome even though it's preselected. There is a workaround of setting the Data property to a list that contains the custom values I need preselected, but it feels clumsy and with the custom values I feel Multiselect should also check the selected values list for chips to render.

    <TelerikMultiSelect 
       @bind-Value="@SelectedCities"
       TItem="string" TValue="string"
       AllowCustom="true"                   
       Width="400px">
    </TelerikMultiSelect>
    
    <span>Selected: @SelectedCities.Count</span>
    
    @code {
        private List<string> SelectedCities { get; set; } = new() {"Rome"};
    }

    1 2 3 4 5 6