﻿<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="https://community.devexpress.com/feed-stylesheets/rss.xsl" media="screen"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dx="https://www.devexpress.com/" xmlns:a10="http://www.w3.org/2005/Atom" version="2.0">
  <channel>
    <title>ASP.NET Team Blog</title>
    <link>https://community.devexpress.com/Blogs/aspnet/default.aspx</link>
    <description>JavaScript, HTML 5, ASP.NET, DevExpress, ASP.NET MVC &amp; WebForms, and News - Mehul Harry's DevExpress blog</description>
    <language>en-US</language>
    <item>
      <guid isPermaLink="false">bd716303-653c-428d-8b8a-a7d998cde032:388278</guid>
      <link>https://community.devexpress.com/Blogs/aspnet/archive/2026/02/24/blazor-june-2026-roadmap-v26-1.aspx</link>
      <category domain="https://community.devexpress.com/Tags/2026">2026</category>
      <category domain="https://community.devexpress.com/Tags/Blazor">Blazor</category>
      <category domain="https://community.devexpress.com/Tags/Featured">Featured</category>
      <category domain="https://community.devexpress.com/Tags/Roadmap">Roadmap</category>
      <category domain="https://community.devexpress.com/Tags/Survey">Survey</category>
      <category domain="https://community.devexpress.com/Tags/v26.1">v26.1</category>
      <title>Blazor — June 2026 Roadmap (v26.1)</title>
      <description>&lt;div class="Note"&gt;The information contained within this blog post details our current/projected development plans. Please note that this information is being shared for INFORMATIONAL PURPOSES ONLY and does not represent a binding commitment on the part of Developer Express Inc. This blog post and the features/products listed within it are subject to change. You should not rely or use this information to help make a purchase decision about Developer Express Inc products.&lt;/div&gt;
&lt;h2 id="blazor-2026-strategy"&gt;Blazor 2026 Strategy&lt;/h2&gt;
&lt;p&gt;As you will see below, we expect to continue extending the capabilities of individual components — but we also want to invest in larger initiatives that span multiple release cycles.&lt;/p&gt;
&lt;p&gt;Many of these initiatives require foundational work (architecture, styling infrastructure, interaction layers, and design-system alignment) before we can commit to a specific release or prepare a complete feature list. Some of this work will not be delivered in the first half of the year (including v26.1).&lt;/p&gt;
&lt;p&gt;Even with our evolving objectives, we want to be transparent about what we are focusing on, why some details are not available yet, and what direction we hope to move toward over time.&lt;/p&gt;
&lt;h3 id="styling-and-layout-foundations"&gt;Styling and Layout Foundations&lt;/h3&gt;
&lt;p&gt;We want DevExpress Blazor components to address more UI needs out of the box, so you can build cohesive layouts with minimal custom CSS.&lt;/p&gt;
&lt;p&gt;Historically, many apps relied on Bootstrap utility classes and layout patterns as the primary styling foundation. Bootstrap is still available, but it does not match modern theme requirements (for instance, misses runtime-configurable accent colors).&lt;/p&gt;
&lt;p&gt;Our direction is to create theme-aware styling alternatives so you do not need to recreate these fundamentals yourself. We are exploring:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DevExpress CSS helper classes for common spacing/layout patterns.&lt;/li&gt;
&lt;li&gt;Lightweight &amp;quot;primitive&amp;quot; components for element composition (for instance, Card, Badge, Avatar).&lt;/li&gt;
&lt;/ul&gt;
&lt;img src="https://community.devexpress.com/blogs/aspnet/26.1/Roadmap/Styling%20and%20Layout%20Foundations%20-%20first%20image%20(2x).png" alt="Styling and Layout Foundations (part 1)"&gt;
&lt;p&gt;We also plan to reduce the amount of fine-tuning needed for complex layouts (alignment, consistent spacing, border/background treatments), especially when size mode can change at runtime. Our goal is to improve visual defaults and introduce new layout-focused settings. These settings will allow you to implement common layouts using component APIs, theme-aware patterns, and helper classes mentioned above.&lt;/p&gt;
&lt;p&gt;Finally, we’ll build demos and project templates that recreate popular app layouts without custom styling.&lt;/p&gt;
&lt;img src="https://community.devexpress.com/blogs/aspnet/26.1/Roadmap/Styling%20and%20Layout%20Foundations%20-%20second%20image%20(2x).png" alt="Styling and Layout Foundations (part 2)"&gt;
&lt;h3 id="classic-theme-deprecation"&gt;Classic Theme Deprecation&lt;/h3&gt;
&lt;p&gt;Blazing Berry, Office White, Purple, Blazing Dark, and Bootstrap-based themes use an old architecture, are hard to maintain, and do not support new styling capabilities (accent colors, public CSS variables, and our UI Kit). We want to focus our efforts on new styling architecture and gradually move away from classic themes. &lt;/p&gt;
&lt;p&gt;We plan to make this transition carefully. Before we deprecate any classic theme, we will prepare viable alternatives, publish clear migration guidance, and give you enough time to move at your own pace.&lt;/p&gt;
&lt;h3 id="new-themes"&gt;New Themes&lt;/h3&gt;
&lt;p&gt;We want to expand our modern theme lineup (starting with Fluent) and evolve our styling infrastructure. Theme directions that we are currently considering:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Material — a frequent request, and a good fit for teams building hybrid solutions that mix UI stacks (including DevExtreme).&lt;/li&gt;
&lt;li&gt;A classic-inspired modern theme — a longer-term option for customers who prefer a look closer to our classic themes.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you have strong preferences on one or the other, we would like to hear your thoughts (please submit a support ticket via the DevExpress Support Center at anytime).&lt;/p&gt;
&lt;h3 id="icon-library"&gt;Icon Library&lt;/h3&gt;
&lt;p&gt;We plan to make our DevExpress Icon Library available to Blazor developers and expand it with new icons. We also expect to introduce a new API that will simplify icon usage for built-in/custom icons, across multiple themes and size modes.&lt;/p&gt;
&lt;h3 id="rtl-support"&gt;RTL Support&lt;/h3&gt;
&lt;p&gt;Right-to-left (RTL) support is an important direction for us and for many of you. We are researching RTL requirements across our Blazor component suite and do preliminary work so components behave more consistently in RTL&amp;nbsp; mode (layout, alignment, and interaction patterns).&lt;/p&gt;
&lt;p&gt;We do not expect RTL support to be available in v26.1, but we will work on it throughout this year.&lt;/p&gt;
&lt;h3 id="performance"&gt;Performance&lt;/h3&gt;
&lt;p&gt;We made significant performance improvements in 2025, and still performance remains an ongoing investment area. We plan to continue researching and testing optimizations across our Blazor component suite. Our focus areas include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Memory throughput and performance under a large number of concurrent sessions.&lt;/li&gt;
&lt;li&gt;Reducing Blazor logical and visual tree size.&lt;/li&gt;
&lt;li&gt;Reducing the number of WebSocket messages per interaction.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once new optimizations are ready, we will add more info to this roadmap.&lt;/p&gt;
&lt;h3 id="security"&gt;Security&lt;/h3&gt;
&lt;p&gt;Security is a core requirement for our components. We already use secure development practices, including automated security scans/reviews. We plan to continue strengthening this process, conducting even more&amp;nbsp;penetration tests, and publish a software bill of materials (SBOM) for DevExpress Blazor.&lt;/p&gt;
&lt;h3 id="accessibility"&gt;Accessibility&lt;/h3&gt;
&lt;p&gt;Accessibility is another key focus area for us. We will&amp;nbsp;continue delivering fixes and improvements across DevExpress Blazor components (keyboard navigation, semantics/ARIA, and visual states).&lt;/p&gt;
&lt;h2 id="share-feedback-on-the-strategy"&gt;Share Feedback on the Strategy&lt;/h2&gt;
&lt;p&gt;We’d like your feedback on these strategic directions before we lock in detailed plans:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Which directions are most important for you in 2026?&lt;/li&gt;
&lt;li&gt;Are we missing any strategic areas?&lt;/li&gt;
&lt;li&gt;Do you have concerns about tradeoffs (for example, themes vs. component features)?&lt;/li&gt;
&lt;li&gt;Any general comments on the strategy or where we should focus first?&lt;/li&gt;
&lt;/ul&gt;
&lt;div data-survey-id="ef59a25a-5f58-4794-90bf-053a4e303c72" data-survey-auth-required="false"&gt;&lt;/div&gt;
&lt;h2 id="product-plans"&gt;Product Plans&lt;/h2&gt;
&lt;p&gt;Our mid-year&amp;nbsp;Blazor roadmap will be updated regularly to reflect development progress. As we get closer to the release, we expect to add additional&amp;nbsp;items and modify the status of planned features. Look for the following labels next to every feature:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;p class="tags"&gt;&lt;span class="not-started"&gt;Planned&lt;/span&gt; — Feature is scheduled but not yet in development.&lt;/p&gt;&lt;/li&gt;
    &lt;li&gt;&lt;p class="tags"&gt;&lt;span class="development"&gt;In Development&lt;/span&gt; — Under active development.&lt;/p&gt;&lt;/li&gt;
    &lt;li&gt;&lt;p class="tags"&gt;&lt;span class="completed"&gt;Coming in EAP v26.1&lt;/span&gt; — Will be available in our first v26.1 early access preview.&lt;/p&gt;&lt;/li&gt;
    &lt;li&gt;&lt;p class="tags"&gt;&lt;span class="completed"&gt;Coming in v26.1&lt;/span&gt; — Will be included in the final v26.1 release.&lt;/p&gt;&lt;/li&gt;
    &lt;li&gt;&lt;p class="tags"&gt;&lt;span class="completed"&gt;Released in v26.1&lt;/span&gt; — Fully implemented and available.&lt;/p&gt;&lt;/li&gt;    
&lt;/ul&gt;
&lt;h3 id="accessibility-enhancements"&gt;Accessibility Enhancements&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Improvements and fixes for our Blazor Data Editors&lt;/li&gt;
&lt;li&gt;Screen reader support for the Blazor Rich Text Editor&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="blazor-smart-paste"&gt;Blazor Smart Paste&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="not-started"&gt;Planned&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We expect to add AI-powered Smart Paste functionality in v26.1.&lt;/p&gt;
&lt;p&gt;Smart Paste will analyze clipboard content and populate each form field with relevant data (to transform traditional copy-and-paste operations).&lt;/p&gt;
&lt;img src="https://www.devexpress.com/subscriptions/i/25.2/25-2-js-form-smart-paste@2x.gif" alt="New Built-in Command Column Action Buttons"&gt;
&lt;h3 id="blazor-grid-treelist"&gt;Blazor Grid &amp;amp; TreeList&lt;/h3&gt;
&lt;h4 id="focus-cells"&gt;Focus Cells&lt;/h4&gt;
&lt;p class="tags"&gt;&lt;span class="not-started"&gt;Planned&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;DevExpress Blazor Grid and TreeList components will support focused cell highlighting. While these components already display focus borders during keyboard navigation, this feature adds a new highlight layer for the active cell (both when users navigate with the keyboard or select a cell with the mouse).&lt;/p&gt;
&lt;p&gt;We will also introduce APIs to identify the focused cell, move focus to a specific cell, and react to focused cell changes.&lt;/p&gt;
&lt;h4 id="total-number-of-records-in-pager"&gt;Total Number of Records in Pager&lt;/h4&gt;
&lt;p class="tags"&gt;&lt;span class="not-started"&gt;Planned&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;DevExpress Blazor Grid and TreeList components will display the total number of records in the Pager to improve data navigation clarity.&lt;/p&gt;
&lt;img src="https://community.devexpress.com/blogs/aspnet/26.1/Roadmap/Grid%20-%20Total%20Number%20of%20Records%20in%20Pager%20(2x).png" alt="Grid - Total Number of Records in Pager"&gt;
&lt;h4 id="built-in-toolbar-items"&gt;Built-in Toolbar Items&lt;/h4&gt;
&lt;p class="tags"&gt;&lt;span class="not-started"&gt;Planned&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We expect to add built-in toolbar items to the DevExpress Blazor Grid and TreeList components. Built-in items will include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Column Chooser&lt;/li&gt;
&lt;li&gt;Export Buttons (CSV, PDF, XLS, and XLSX)&lt;/li&gt;
&lt;li&gt;Search Box&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="built-in-criteria-selector-menu"&gt;Filter Row — Built-in criteria selector menu&lt;/h4&gt;
&lt;p class="tags"&gt;&lt;span class="not-started"&gt;Planned&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We hope to introduce a Criteria Selector Menu for our Blazor Grid and TreeList Filter Row. This menu allows users to select filter conditions directly within the row editor and apply them to the entered value. &lt;/p&gt;
&lt;img src="https://community.devexpress.com/blogs/aspnet/26.1/Roadmap/Grid%20-%20Built-in%20criteria%20selector%20menu%20(2x).png" alt="Grid - Built-in criteria selector menu"&gt;
&lt;h4 id="bind-filter-on-input-option"&gt;Filter Row — Bind Filter On Input Option&lt;/h4&gt;
&lt;p class="tags"&gt;&lt;span class="not-started"&gt;Planned&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Filter Row Data Editors will support on‑input data binding mode. In this mode, DevExpress Blazor Grid and TreeList components apply filters as users type (no need to press Enter). &lt;/p&gt;
&lt;h3 id="ui-ux-enhancements"&gt;UI/UX Enhancements&lt;/h3&gt;
&lt;h4 id="vertical-grid-line-visibility"&gt;Vertical Grid Line Visibility&lt;/h4&gt;
&lt;p class="tags"&gt;&lt;span class="not-started"&gt;Planned&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We will add an option to hide column lines (vertical separators between adjacent columns) in our Blazor Grid and TreeList components.&lt;/p&gt;
&lt;img src="https://community.devexpress.com/blogs/aspnet/26.1/Roadmap/Grid%20-%20Vertical%20Grid%20Line%20Visibility%20(2x).png" alt="Column Lines Visibility Customization"&gt;
&lt;h4 id="striped-rows"&gt;Striped Rows&lt;/h4&gt;
&lt;p class="tags"&gt;&lt;span class="not-started"&gt;Planned&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We plan to introduce an option to highlight alternating (odd) rows in our&amp;nbsp;Blazor Grid and TreeList with a different style (to enhance readability).&lt;/p&gt;
&lt;img src="https://community.devexpress.com/blogs/aspnet/26.1/Roadmap/Grid%20-%20Striped%20Rows%20(2x).png" alt="Striped Rows"&gt;
&lt;h4 id="filter-menu-button-new-on-hover-display-mode"&gt;Filter Menu Button — New On‑Hover Display Mode&lt;/h4&gt;
&lt;p class="tags"&gt;&lt;span class="not-started"&gt;Planned&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;DevExpress Blazor Grid and TreeList will support on‑hover display mode for Filter Menu buttons. When enabled, buttons will appear after users hover over column headers. This mode helps create a cleaner UI and avoid column caption truncation.&lt;/p&gt;
&lt;h4 id="custom-row-height"&gt;Custom Row Height&lt;/h4&gt;
&lt;p class="tags"&gt;&lt;span class="not-started"&gt;Planned&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;In v26.1, you will be able to specify a minimum row height for the DevExpress Blazor Grid and TreeList. This new option allows you to adjust visual density by increasing/decreasing row spacing and gives you more control over row appearance.&lt;/p&gt;
&lt;h3 id="blazor-treelist-unbound-columns"&gt;Blazor TreeList — Unbound Columns&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="development"&gt;In Development&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We plan to introduce unbound column support for the DevExpress Blazor TreeList component. Unbound columns display values that are not stored in the underlying data source. Our TreeList can calculate these values on the fly or derive them from other fields. Use unbound columns to display supplementary/computed data without modifying the original data model.&lt;/p&gt;
&lt;h3 id="blazor-data-editors"&gt;Blazor Data Editors&lt;/h3&gt;
&lt;h4 id="textbox-password-button"&gt;TextBox — Password Button&lt;/h4&gt;
&lt;p class="tags"&gt;&lt;span class="not-started"&gt;Planned&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;v26.1 will include a built‑in button that displays/hides a password within the DevExpress Blazor TextBox editor. This button allows users to verify text they have entered.&lt;/p&gt;
&lt;h4 id="spinedit-maskedinput-disable-arrow-keys"&gt;SpinEdit &amp;amp; MaskedInput — Disable Arrow Keys&lt;/h4&gt;
&lt;p class="tags"&gt;&lt;span class="not-started"&gt;Planned&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Both DevExpress Blazor SpinEdit and MaskedInput components will allow you to prevent a change to values&amp;nbsp;when users press Up/Down arrow keys.&lt;/p&gt;
&lt;h4 id="maskedinput-disable-mouse-wheel"&gt;MaskedInput — Disable Mouse Wheel&lt;/h4&gt;
&lt;p class="tags"&gt;&lt;span class="not-started"&gt;Planned&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Our Blazor MaskedInput will allow you to prevent a change to values&amp;nbsp;when users scroll&amp;nbsp;the mouse wheel. This option prevents accidental modifications during page/content scrolling.&lt;/p&gt;
&lt;h4 id="focusable-custom-buttons"&gt;Focusable Custom Buttons&lt;/h4&gt;
&lt;p&gt;Our Blazor Data Editors will include a new Focusable option for custom buttons. Once activated, users can interact with custom buttons using the keyboard.&lt;/p&gt;
&lt;h3 id="blazor-formlayout"&gt;Blazor FormLayout&lt;/h3&gt;
&lt;h4 id="new-caption-position-mode"&gt;New Caption Position Mode&lt;/h4&gt;
&lt;p class="tags"&gt;&lt;span class="not-started"&gt;Planned&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We expect to extend the CaptionPosition property with a new Auto mode. In this mode, Form Layout will automatically switch the caption to a vertical position when horizontal space is insufficient. This behavior matches the current implementation of the Horizontal mode.&lt;/p&gt;
&lt;p&gt;With this update:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Auto becomes the new default caption position and enables automatic switching based on available space.&lt;/li&gt;
&lt;li&gt;Horizontal mode will no longer change caption position and will always display captions horizontally, regardless of layout constraints.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="api-enhancements"&gt;API Enhancements&lt;/h4&gt;
&lt;p class="tags"&gt;&lt;span class="not-started"&gt;Planned&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The DevExpress Blazor FormLayout component will include the following new API members:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;TabsPosition — Specifies&amp;nbsp;tab header position.&lt;/li&gt;
&lt;li&gt;AllowClose | AllowTabReorder — Allows users to close/reorder tabs.&lt;/li&gt;
&lt;li&gt;TabClosing | TabReordering — Allows you to handle tab closing/reordering actions.&lt;/li&gt;
&lt;li&gt;TabPageEnabled — Allows you to disable a tab page.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="blazor-dialog-service-content-template"&gt;Blazor Dialog Service - Content Template&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="not-started"&gt;Planned&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We hope to add a content template option for message dialogs displayed via the DevExpress Blazor Dialog Service. This option will allow you to customize the dialog body: format message text, add links, or display additional interactive elements.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;private async Task OpenConfirmDialogAsync() {
    Result = await DialogService.ConfirmAsync(new MessageBoxOptions() {
        ContentTemplate = @&amp;lt;div&amp;gt;
            &amp;lt;p&amp;gt;Are you sure you want to delete this record?&amp;lt;/p&amp;gt;
            &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;This action cannot be undone.&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;
        &amp;lt;/div&amp;gt;,
        OkButtonText = &amp;quot;Yes&amp;quot;,
        CancelButtonText = &amp;quot;No&amp;quot;,
        RenderStyle = MessageBoxRenderStyle.Danger,
    });
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id="blazor-layout-navigation"&gt;Blazor Layout &amp;amp; Navigation&lt;/h3&gt;
&lt;h4 id="treeview-accordion-menu-toolbar-data-mapping-api-enhancements"&gt;TreeView, Accordion, Menu &amp;amp; Toolbar — Data Mapping API Enhancements&lt;/h4&gt;
&lt;p class="tags"&gt;&lt;span class="not-started"&gt;Planned&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We plan to extend Data Mapping APIs available for DevExpress Blazor TreeView, Accordion, Menu, and Toolbar components. New APIs will allow you to implement more business scenarios using data binding (instead of static Razor markup).&lt;/p&gt;
&lt;p&gt;Use cases include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Build navigation from a shared model (for instance, a sitemap or route list).&lt;/li&gt;
&lt;li&gt;Display/hide items based on permissions/flags.&lt;/li&gt;
&lt;li&gt;Generate hierarchical structures (groups, child items) based on data.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class="language-ts"&gt;&amp;lt;DxTreeView Data=&amp;quot;@Data&amp;quot;&amp;gt;
    &amp;lt;DataMappings&amp;gt;
        &amp;lt;DxTreeViewDataMapping Text=&amp;quot;Name&amp;quot;
                               Key=&amp;quot;Id&amp;quot;
                               BadgeText=&amp;quot;Badge&amp;quot;
                               ParentKey=&amp;quot;CategoryId&amp;quot;/&amp;gt;
    &amp;lt;/DataMappings&amp;gt;
&amp;lt;/DxTreeView&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id="accordion-cache-collapsed-content"&gt;Accordion — Cache Collapsed Content&lt;/h4&gt;
&lt;p class="tags"&gt;&lt;span class="not-started"&gt;Planned&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The DevExpress Blazor Accordion will allow you to cache collapsed group content. When caching is active, the Accordion retains collapsed content and does not need to recreate it once the group is expanded.&lt;/p&gt;
&lt;p&gt;This feature is useful for groups containing complex UI content that is costly to re-initialize (for instance, Forms with validation, Charts, or Data Grids).&lt;/p&gt;
&lt;h3 id="blazor-pivot-table"&gt;Blazor Pivot Table&lt;/h3&gt;
&lt;h4 id="server-mode"&gt;Server Mode&lt;/h4&gt;
&lt;p class="tags"&gt;&lt;span class="development"&gt;In Development&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We expect to support Server Mode in the DevExpress Pivot Table component. In this mode, the Pivot Table retrieves data on demand and executes grouping, filtering, and summary calculations on the server. Server‑side data processing optimizes performance when working with large datasets and complex filters. &lt;/p&gt;
&lt;h4 id="drill-down-support"&gt;Drill‑Down Support&lt;/h4&gt;
&lt;p class="tags"&gt;&lt;span class="not-started"&gt;Planned&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We plan to support drill‑down scenarios in the DevExpress Blazor Pivot Table. Drill‑down allows you to retrieve the underlying records used to calculate a specific summary value. This capability is useful when you need to examine the data behind aggregated results.&lt;/p&gt;
&lt;p&gt;New APIs will include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CellClick — Provides access to the underlying data of the clicked cell.&lt;/li&gt;
&lt;li&gt;CreateDrillDownDataSource(options) — Returns a drill‑down data source.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You will be able to bind underlying data to our Blazor Grid component and allow users to review detailed records within the same page.&lt;/p&gt;
&lt;h3 id="blazor-themes"&gt;Blazor Themes&lt;/h3&gt;
&lt;h4 id="fluent-themes-high-contrast-mode"&gt;Fluent Themes — High Contrast Mode&lt;/h4&gt;
&lt;p class="tags"&gt;&lt;span class="development"&gt;In Development&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;DevExpress Blazor Fluent themes will support high contrast mode in our June release. They will automatically modify colors if Windows &lt;a href="https://support.microsoft.com/en-us/windows/turn-high-contrast-mode-on-or-off-in-windows-909e9d89-a0f9-a3a9-b993-7a6dcee85025"&gt;high contrast mode&lt;/a&gt; is active.&lt;/p&gt;
&lt;h2 id="blazor-reporting"&gt;Blazor Reporting&lt;/h2&gt;
&lt;p&gt;Learn more:&amp;nbsp;&lt;a href="https://community.devexpress.com/blogs/reporting/archive/2026/02/10/reporting-amp-bi-dashboard-june-2026-roadmap-v26-1.aspx" target="_blank"&gt;Reporting &amp;amp; BI Dashboard — June 2026 Roadmap (v26.1)&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="your-feedback"&gt;Your Feedback Matters&lt;/h2&gt;
&lt;div data-survey-id="73a2487e-13ca-41b5-9bc3-3d4f1ef4f317" data-survey-auth-required="false"&gt;&lt;/div&gt;</description>
      <pubDate>Tue, 24 Feb 2026 08:30:00 Z</pubDate>
      <dc:creator>Slava Khudyakov (DevExpress)</dc:creator>
      <dx:excerpt>Thank you for choosing DevExpress and for your on-going support. We value your business. As you will see below, we expect to continue extending the capabilities of individual components — but we also want to invest in larger initiatives that span multiple release cycles.&#xD;
&#xD;
</dx:excerpt>
    </item>
    <item>
      <guid isPermaLink="false">bd716303-653c-428d-8b8a-a7d998cde032:388264</guid>
      <link>https://community.devexpress.com/Blogs/aspnet/archive/2026/01/08/devexpress-blazor-ai-chat-agent2agent-a2a-protocol-integration.aspx</link>
      <category domain="https://community.devexpress.com/Tags/A2A">A2A</category>
      <category domain="https://community.devexpress.com/Tags/Agent">Agent</category>
      <category domain="https://community.devexpress.com/Tags/AI">AI</category>
      <category domain="https://community.devexpress.com/Tags/Blazor">Blazor</category>
      <category domain="https://community.devexpress.com/Tags/Chat+UI">Chat UI</category>
      <category domain="https://community.devexpress.com/Tags/LLM">LLM</category>
      <title>DevExpress Blazor AI Chat — Agent2Agent (A2A) Protocol Integration</title>
      <description>&lt;p&gt;Modern AI-powered applications increasingly implement automated functions through specialized AI agents. The statistics show impressive growth: &lt;a href="https://www.index.dev/blog/ai-agents-statistics" target="_blank" title="50+ Key AI Agent Statistics and Adoption Trends in 2025"&gt;in 2025, 85% of organizations have integrated AI agents into at least one workflow&lt;/a&gt;. Users now expect conversational interfaces for various business tasks: customer service automation, personalized shopping assistance, financial transaction management, content creation, and streamlined workflow coordination.&lt;/p&gt;
&lt;p&gt;The key distinction between AI agents and working with standard large language models lies in a simple formula: an agent equals LLM plus instructions and tools it can invoke, representing&amp;nbsp;an autonomous system. &lt;/p&gt;&lt;p&gt;&lt;img src="https://community.devexpress.com/blogs/aspnet/25.2/a2a/a2a-what-is-an-agent.png" alt="What is an AI Agent — Diagram" style="width:2360px;height:1336px;"&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Source/Credit: &lt;a href="https://www.youtube.com/watch?v=DUdRdeUtuZQ" target="_blank" title="Azure AI Foundry: The AI app and Agent Factory | BRK155"&gt;Microsoft Developer YouTube channel&lt;/a&gt;.&amp;nbsp;&lt;/em&gt;&lt;/p&gt;&lt;p&gt;While LLMs can only generate text, agents extend these capabilities into actionable intelligence by integrating external APIs, accessing databases, managing files, and connecting with enterprise systems. This transforms them from passive text generators into autonomous systems capable of executing complex, multi-step tasks. One of the first agents that was introduced in the industry were&amp;nbsp;ChatGPT plugins that added web browsing and code interpreter capabilities (allowing the LLM to search the Web and execute code while replying to a user query).&lt;/p&gt;
&lt;p&gt;In April 2025, Google introduced its&amp;nbsp;&lt;a target="_blank" href="https://a2a-protocol.org/latest"&gt;Agent2Agent (A2A) protocol&lt;/a&gt; — an open standard for standardizing communication between agents. The protocol has gained support from over 150 organizations, including tech giants like Microsoft, Salesforce, SAP, ServiceNow, and Amazon Web Services. The protocol&amp;#39;s advantage lies in enabling agents developed by different teams on various platforms to seamlessly exchange information and coordinate actions, creating essentially an &amp;quot;internet of agents&amp;quot; or &amp;quot;agentic web&amp;quot; — similar to how HTTP allowed websites to interact with each other.&lt;/p&gt;
&lt;p&gt;The benefits notwithstanding, integrating agents with user interface components presents technical challenges. Agents use structured data exchange formats and support complex task lifecycles, while chat components expect simple text messages and streaming responses. In this article, I describe how to connect the &lt;a target="_blank" href="https://docs.devexpress.com/Blazor/405290/components/ai-chat"&gt;DevExpress Blazor AI Chat&lt;/a&gt; component to A2A protocol-compliant agents with a small adapter. The implementation hosts four agents in separate ASP.NET Core servers and switches agents at runtime within a single chat UI. The sample also includes a &lt;em&gt;Researcher&lt;/em&gt; agent from the official &lt;a target="_blank" href="https://github.com/a2aproject/a2a-dotnet"&gt;Microsoft A2A .NET SDK samples&lt;/a&gt; to show compatibility with existing agents.&lt;/p&gt;
&lt;div class="Note"&gt;
    &lt;p&gt;This example focuses on agent connectivity rather than orchestration. The A2A protocol supports advanced inter-agent patterns such as routing, delegation, and task handoffs, but this sample does not implement them. Any A2A-compliant agent can connect to the Blazor AI Chat component with the approach documented here.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id="architectureoverview"&gt;Architecture Overview&lt;/h2&gt;
&lt;p&gt;The solution uses a distributed layout. A shared library defines all agent classes and base types. Four ASP.NET Core projects host &lt;strong&gt;Poem&lt;/strong&gt;, &lt;strong&gt;Shakespearean Style&lt;/strong&gt;, &lt;strong&gt;Task&lt;/strong&gt;, and &lt;strong&gt;Researcher&lt;/strong&gt; agents. Each server runs on its own port and exposes a single A2A endpoint at &lt;code&gt;/agent&lt;/code&gt;. A Blazor Server app embeds the &lt;strong&gt;DevExpress AI Chat&lt;/strong&gt; component and talks to agents through &lt;code&gt;IChatClient&lt;/code&gt;-based adapters.&lt;/p&gt;
&lt;h2 id="a2acompliantagentsserverapp"&gt;Agent Server Apps&lt;/h2&gt;
&lt;p&gt;Each agent server follows the same pattern. The example below shows a minimal setup that maps the A2A pipeline to &lt;code&gt;/agent&lt;/code&gt; and wires an agent to a task manager.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;using A2A;
using A2A.AspNetCore;
using Azure;
using Azure.AI.OpenAI;
using A2AAgents.Shared;
using A2AAgentsServer.Agents;
using Microsoft.Extensions.AI;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

TaskManager taskManager = new TaskManager();

var settings = builder.Configuration.GetSection(&amp;quot;AzureOpenAISettings&amp;quot;).Get&amp;lt;AzureOpenAIServiceSettings&amp;gt;();
if (settings == null || string.IsNullOrEmpty(settings.Endpoint) || string.IsNullOrEmpty(settings.Key) || string.IsNullOrEmpty(settings.DeploymentName))
    throw new InvalidOperationException(&amp;quot;Specify Azure OpenAI endpoint, key, and deployment name in appsettings.json.&amp;quot;);
var chatClient = new AzureOpenAIClient(new Uri(settings.Endpoint), new AzureKeyCredential(settings.Key))
    .GetChatClient(settings.DeploymentName)
    .AsIChatClient();

var agent = new PoemAgent(chatClient, taskManager);

app.UseHttpsRedirection();
app.MapA2A(taskManager, &amp;quot;/agent&amp;quot;);
app.Run();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Shakespearean Style, Task, and Researcher servers use the same structure. They differ by agent type and the port configured in each project&amp;#39;s launch settings.&lt;/p&gt;
&lt;h2 id="protocolcompliancevalidationwitha2ainspector"&gt;Protocol Compliance Validation with a2a-inspector&lt;/h2&gt;
&lt;p&gt;All agents pass validation with the &lt;a target="_blank" href="https://github.com/a2aproject/a2a-inspector" title="a2a-inspector tool – GitHub Repository"&gt;a2a-inspector tool&lt;/a&gt;. The inspector checks Agent Card metadata, message format, and streaming support, task state signaling for task agents, and protocol version compatibility.&lt;/p&gt;
&lt;img src="https://community.devexpress.com/blogs/aspnet/25.2/a2a/a2a-inspector-poem-agent.png" alt="a2a-inspector - The Poem Agent Validation Screenshot" style="width:1616px;height:2400px;"&gt;
&lt;h2 id="bridginga2atoichatclient"&gt;Bridging A2A to IChatClient&lt;/h2&gt;
&lt;p&gt;The key to this integration is a lightweight adapter that translates between A2A protocol messages and the &lt;code&gt;IChatClient&lt;/code&gt; interface used by DevExpress Blazor AI Chat to interact with LLMs. This adapter maintains conversation context, converts chat messages to A2A protocol format, and streams responses back to the UI:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public sealed class MessageAgentChatClient : DelegatingChatClient {
    private readonly A2AClient _agentClient;
    private readonly string _contextId;

    public MessageAgentChatClient(IChatClient innerClient, A2AClient agentClient, string contextId) 
        : base(innerClient) {
        _agentClient = agentClient ?? throw new ArgumentNullException(nameof(agentClient));
        _contextId = $&amp;quot;{contextId}-{Guid.NewGuid()}&amp;quot;;
    }

    public override async IAsyncEnumerable&amp;lt;ChatResponseUpdate&amp;gt; GetStreamingResponseAsync(
        IEnumerable&amp;lt;ChatMessage&amp;gt; messages, 
        ChatOptions? options = null,
        [EnumeratorCancellation] CancellationToken cancellationToken = default) {

        var sendParams = new MessageSendParams { 
            Message = CreateA2AMessage(messages) 
        };

        await foreach (var item in _agentClient.SendMessageStreamingAsync(sendParams, cancellationToken)) {
            if (item.Data is AgentMessage message &amp;amp;&amp;amp; message.Parts.FirstOrDefault() is TextPart textPart) {
                yield return new ChatResponseUpdate(ChatRole.Assistant, textPart.Text);
            }
        }
    }
    
    private AgentMessage CreateA2AMessage(IEnumerable&amp;lt;ChatMessage&amp;gt; messages) {
            return new AgentMessage() {
                Role = MessageRole.User,
                ContextId = _contextId,
                Parts = [new TextPart() { Text = messages.Last().Text }]
            };
        }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="runtimeagentselection"&gt;Runtime Agent Selection&lt;/h2&gt;
&lt;p&gt;The app registers each agent as a keyed &lt;code&gt;IChatClient&lt;/code&gt; service and switches between them at runtime through a simple dropdown.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;// Register each A2A agent as a keyed IChatClient service
builder.Services.AddKeyedScoped&amp;lt;IChatClient&amp;gt;(AgentsEndpoints.PoemAgent, (provider, key) =&amp;gt;
    new MessageAgentChatClient(chatClient, 
        new A2AClient(new Uri(AgentsEndpoints.PoemAgent)), 
        AgentsEndpoints.PoemAgent));

builder.Services.AddKeyedScoped&amp;lt;IChatClient&amp;gt;(AgentsEndpoints.ShakespeareanStyleAgent, (provider, key) =&amp;gt;
    new MessageAgentChatClient(chatClient, 
        new A2AClient(new Uri(AgentsEndpoints.ShakespeareanStyleAgent)), 
        AgentsEndpoints.ShakespeareanStyleAgent));

builder.Services.AddKeyedScoped&amp;lt;IChatClient&amp;gt;(AgentsEndpoints.TaskAgent, (provider, key) =&amp;gt;
    new TaskAgentChatClient(chatClient, 
        new A2AClient(new Uri(AgentsEndpoints.TaskAgent)), 
        AgentsEndpoints.TaskAgent));

builder.Services.AddKeyedScoped&amp;lt;IChatClient&amp;gt;(AgentsEndpoints.ResearcherAgent, (provider, key) =&amp;gt;
    new TaskAgentChatClient(chatClient, 
        new A2AClient(new Uri(AgentsEndpoints.ResearcherAgent)), 
        AgentsEndpoints.ResearcherAgent));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;a target="_blank" href="https://docs.devexpress.com/Blazor/DevExpress.AIIntegration.Blazor.Chat.DxAIChat.ChatClientServiceKey"&gt;ChatClientServiceKey&lt;/a&gt; property (available with DevExpress v25.1.4) enables runtime switching between multiple &lt;code&gt;IChatClient&lt;/code&gt; services.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;DxAIChat @ref=&amp;quot;_dxAIChat&amp;quot; 
          UseStreaming=&amp;quot;true&amp;quot; 
          ChatClientServiceKey=&amp;quot;@CurrentServiceKey&amp;quot;
          CssClass=&amp;quot;chat-container&amp;quot; /&amp;gt;

&amp;lt;DxComboBox Data=&amp;quot;@AgentOptions&amp;quot;
            TextFieldName=&amp;quot;nameof(AgentOption.Text)&amp;quot;
            ValueFieldName=&amp;quot;nameof(AgentOption.Value)&amp;quot;
            @bind-Value=&amp;quot;@CurrentServiceKey&amp;quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="welcomechatscreen"&gt;Welcome Chat Screen&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;EmptyMessageAreaTemplate&lt;/code&gt; shows agent descriptions and instructions when the chat is empty. This helps users understand each agent and start a conversation quickly.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;EmptyMessageAreaTemplate&amp;gt;
        &amp;lt;div class=&amp;quot;empty-message-area&amp;quot;&amp;gt;
            &amp;lt;h4&amp;gt;🤖 Multi-Agent AI Chat&amp;lt;/h4&amp;gt;
            &amp;lt;p&amp;gt;Welcome to the Agent-to-Agent communication platform! Choose your specialized AI agent and start chatting.&amp;lt;/p&amp;gt;

            &amp;lt;div&amp;gt;
                &amp;lt;h5&amp;gt;Available Agents:&amp;lt;/h5&amp;gt;
                &amp;lt;ul class=&amp;quot;agents-list&amp;quot;&amp;gt;
                    &amp;lt;li&amp;gt;&amp;lt;strong&amp;gt;🎭 Poem Agent:&amp;lt;/strong&amp;gt; Enter 2-5 keywords and I&amp;#39;ll generate a short lyrical poem&amp;lt;/li&amp;gt;
                    &amp;lt;li&amp;gt;&amp;lt;strong&amp;gt;📜 Shakespearean Style Agent:&amp;lt;/strong&amp;gt; Transform your text into William Shakespeare&amp;#39;s style&amp;lt;/li&amp;gt;
                    &amp;lt;li&amp;gt;&amp;lt;strong&amp;gt;📋 Task Agent:&amp;lt;/strong&amp;gt; Help plan and execute task descriptions&amp;lt;/li&amp;gt;
                    &amp;lt;li&amp;gt;&amp;lt;strong&amp;gt;Researcher Agent:&amp;lt;/strong&amp;gt; Agent from https://github.com/a2aproject/a2a-dotnet/blob/main/samples/AgentServer/ResearcherAgent.cs &amp;lt;/li&amp;gt;
                    &amp;lt;li&amp;gt;&amp;lt;strong&amp;gt;💬 Default Chat Client:&amp;lt;/strong&amp;gt; Standard AI conversation&amp;lt;/li&amp;gt;
                &amp;lt;/ul&amp;gt;
            &amp;lt;/div&amp;gt;

            &amp;lt;div&amp;gt;
                &amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;Current Agent:&amp;lt;/strong&amp;gt; &amp;lt;span class=&amp;quot;current-agent-badge&amp;quot;&amp;gt;@AgentOptions.FirstOrDefault(x =&amp;gt; x.Value == CurrentServiceKey)?.Text&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;
            &amp;lt;/div&amp;gt;

            &amp;lt;p class=&amp;quot;help-text&amp;quot;&amp;gt;
                &amp;lt;small&amp;gt;💡 Select an agent from the dropdown above, then type your message to start the conversation!&amp;lt;/small&amp;gt;
            &amp;lt;/p&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/EmptyMessageAreaTemplate&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;img src="https://community.devexpress.com/blogs/aspnet/25.2/a2a/dx-ai-chat-empty-state.png" alt="DevExpress Blazor AI Chat — An Empty State Screen" style="width:1672px;height:1368px;"&gt;
&lt;h2 id="userexperience"&gt;User Experience&lt;/h2&gt;
&lt;p&gt;Users can select Poem, Shakespearean Style, Task, or Researcher agents via a dropdown, utilize manual handoffs by copying output&amp;nbsp;between agents to simulate composition workflows, and enjoy streaming responses that preserve the responsive feel of AI interactions. The video below demonstrates project functionality in action:&lt;/p&gt;
&lt;video controls=""&gt;
    &lt;source src="https://community.devexpress.com/blogs/aspnet/25.2/a2a/dx-ai-chat-agents-in-action.mp4" type="video/mp4"&gt;
    Your browser does not support the video tag.
&lt;/video&gt;
&lt;h2 id="downloadthecompleteexample"&gt;Download the Complete Example&lt;/h2&gt;
&lt;p&gt;To get started with this integration, clone the &lt;a target="_blank" href="https://github.com/DevExpress-Examples/blazor-ai-chat-a2a-mode"&gt;Blazor AI Chat — Communicate with Agents That Implement Agent2Agent (A2A) Protocol&lt;/a&gt; repository from GitHub and configure your AI service provider in &lt;code&gt;appsettings.json&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-json"&gt;{
  &amp;quot;AzureOpenAISettings&amp;quot;: {
    &amp;quot;Endpoint&amp;quot;: &amp;quot;https://your-instance.openai.azure.com/&amp;quot;,
    &amp;quot;Key&amp;quot;: &amp;quot;your-api-key&amp;quot;,
    &amp;quot;DeploymentName&amp;quot;: &amp;quot;your-model-name&amp;quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id="configureagentendpoints"&gt;Configure Agent Endpoints&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;AgentsEndpoints&lt;/code&gt; class centralizes agent URLs. The app uses HTTP by default and includes HTTPS alternatives as comments.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public static class AgentsEndpoints {
    public const string PoemAgent = &amp;quot;http://localhost:5003/agent&amp;quot;;
    public const string ShakespeareanStyleAgent = &amp;quot;http://localhost:5005/agent&amp;quot;;
    public const string TaskAgent = &amp;quot;http://localhost:5007/agent&amp;quot;;
    public const string ResearcherAgent = &amp;quot;http://localhost:5009/agent&amp;quot;;
    // HTTPS alternatives:
    // public const string PoemAgent = &amp;quot;https://localhost:5004/agent&amp;quot;;
    // public const string ShakespeareanStyleAgent = &amp;quot;https://localhost:5006/agent&amp;quot;;
    // public const string TaskAgent = &amp;quot;https://localhost:5008/agent&amp;quot;;
    // public const string ResearcherAgent = &amp;quot;https://localhost:5010/agent&amp;quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Start the four agent servers first (&lt;code&gt;PoemAgentServer&lt;/code&gt; on &lt;i&gt;http://localhost:5003&lt;/i&gt;, &lt;code&gt;ShakespeareanStyleAgentServer&lt;/code&gt; on &lt;i&gt;http://localhost:5005&lt;/i&gt;, &lt;code&gt;TaskAgentServer&lt;/code&gt; on &lt;i&gt;http://localhost:5007&lt;/i&gt;, &lt;code&gt;ResearcherAgentServer&lt;/code&gt; on &lt;i&gt;http://localhost:5009&lt;/i&gt;). Wait until each reports that it is listening on its port. Then start the Blazor Server app, select an agent in the UI, and start chatting. You can switch agents at runtime. The implementation supports Azure OpenAI, OpenAI API, and local runtimes like Ollama with minimal changes.&lt;/p&gt;
&lt;h2 id="yourfeedbackmatters"&gt;Your Feedback Matters&lt;/h2&gt;
&lt;p&gt;We&amp;#39;re gathering feedback to prioritize future enhancements to our AI agent integration capabilities. Please take a moment to share your experience and help us shape future AI integration features:&lt;/p&gt;
&lt;div data-survey-id="417c2966-5bc4-4437-a986-854132e72d76" data-survey-auth-required="false"&gt;&lt;/div&gt;</description>
      <pubDate>Thu, 08 Jan 2026 01:10:00 Z</pubDate>
      <dc:creator>Dmitry Tokmachev (DevExpress)</dc:creator>
    </item>
    <item>
      <guid isPermaLink="false">bd716303-653c-428d-8b8a-a7d998cde032:388262</guid>
      <link>https://community.devexpress.com/Blogs/aspnet/archive/2025/08/18/devexpress-blazor-ai-chat-tool-call-confirmation.aspx</link>
      <category domain="https://community.devexpress.com/Tags/AI">AI</category>
      <category domain="https://community.devexpress.com/Tags/Blazor">Blazor</category>
      <category domain="https://community.devexpress.com/Tags/Chat+UI">Chat UI</category>
      <category domain="https://community.devexpress.com/Tags/Security">Security</category>
      <category domain="https://community.devexpress.com/Tags/Tool+Calling">Tool Calling</category>
      <title>DevExpress Blazor AI Chat — Tool Call Confirmation</title>
      <description>&lt;p&gt;Modern AI-powered applications often execute tools automatically in response to user queries. While this automation embraces the potential of LLMs and improves user experiences, it can introduce security risks when sensitive operations are invoked without explicit user consent — for example, modifying databases, sending emails, or making API calls to external services.&lt;/p&gt;

&lt;p&gt;This post outlines the purpose of our &lt;strong&gt;Tool Call Confirmation API layer&lt;/strong&gt; and associated customizable interface&amp;nbsp;for the DevExpress Blazor AI Chat component. As you would expect, our solution intercepts AI-initiated function calls, generates&amp;nbsp;detailed confirmation dialogs, and requires user approval before execution. This UI pattern is common in GitHub Copilot Chat, Cursor, Claude, and other AI-powered applications with MCP support.&lt;/p&gt;

&lt;img src="https://community.devexpress.com/blogs/aspnet/25.2/ai-tool-call-confirm/blazor-ai-chat-tool-calling-confirmation.png" alt="DevExpress Blazor AI Chat — Tool Calling Confirmation UI" style="width:725px;height:528px;"&gt;



&lt;p&gt;In this post, I&amp;#39;ll walk you through our AI Chat confirmation system, its key components, and customization options (and of course show you how to add this security layer to your AI-powered Blazor applications using the DevExpress Blazor AI Chat control).&lt;/p&gt;&lt;h2 id="the-challenge-balancing-automation-and-security"&gt;The Challenge: Balancing Automation and Security&lt;/h2&gt;

&lt;p&gt;AI function calling is a powerful resource - one that allows models to interact seamlessly with app functionality. However, this power must be used responsibly. Consider the following usage scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An AI model deletes user data in response to an ambiguous request.&lt;/li&gt;
&lt;li&gt;Unmanaged API calls generate unexpected costs or trigger external processes.&lt;/li&gt;
&lt;li&gt;Functions modify application state or UI without the user&amp;#39;s knowledge.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The technique described in this post strikes a balance between convenience and control: it preserves the benefits of automated tool calling and gives users explicit authority over sensitive or irreversible operations.&lt;/p&gt;

&lt;h2 id="getting-started"&gt;Before You Start&lt;/h2&gt;
&lt;p&gt;Create and configure the DevExpress Blazor Chat (&amp;nbsp;&lt;code&gt;DxAIChat&lt;/code&gt;&amp;nbsp;) component in your Blazor application. For setup instructions, review the following: Blazor Chat&amp;nbsp;&lt;a href="https://docs.devexpress.com/Blazor/DevExpress.AIIntegration.Blazor.Chat.DxAIChat#add-an-ai-chat-to-a-project" target="_blank"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This example targets Azure OpenAI, but the solution is compatible with any AI service that implements the &lt;code&gt;IChatClient&lt;/code&gt; interface from the &amp;quot;Microsoft.Extensions.AI&amp;quot; library.&lt;/p&gt;

&lt;p&gt;The following code in &lt;i&gt;Program.cs&lt;/i&gt; defines the basic configuration:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-csharp"&gt;
using Azure;
using Azure.AI.OpenAI;
using Microsoft.Extensions.AI;

var builder = WebApplication.CreateBuilder(args);

// Replace with your endpoint, API key, and model&amp;#39;s deployment name
string azureOpenAIEndpoint = Environment.GetEnvironmentVariable(&amp;quot;AZURE_OPENAI_ENDPOINT&amp;quot;);
string azureOpenAIKey = Environment.GetEnvironmentVariable(&amp;quot;AZURE_OPENAI_API_KEY&amp;quot;);
string deploymentName = &amp;quot;your-model-deployment-name&amp;quot;;

var azureChatClient = new AzureOpenAIClient(
    new Uri(azureOpenAIEndpoint),
    new AzureKeyCredential(azureOpenAIKey))
    .GetChatClient(deploymentName)
    .AsIChatClient();

builder.Services.AddDevExpressBlazor();
builder.Services.AddDevExpressAI();
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id="architecture-overview"&gt;Architecture Overview&lt;/h2&gt;

&lt;ul&gt;
    &lt;li&gt;
        &lt;p&gt;
            &lt;strong&gt;&lt;code&gt;IToolCallFilter&lt;/code&gt;&lt;/strong&gt;
            &lt;br&gt;
            Manages AI tool calls before they are executed.
        &lt;/p&gt;
    &lt;/li&gt;
    
    &lt;li&gt;
        &lt;p&gt;
        	&lt;strong&gt;&lt;code&gt;CustomFunctionInvokingChatClient&lt;/code&gt;&lt;/strong&gt;
        	&lt;br&gt;
        	Extends the default behavior used to invokes tools.
    	&lt;/p&gt;
    &lt;/li&gt;
    
    &lt;li&gt;
    	&lt;p&gt;
            &lt;strong&gt;&lt;code&gt;CustomFunctionInvokingChatClientExtensions&lt;/code&gt;&lt;/strong&gt;
            &lt;br&gt;
            
        The Fluent API allows you to leverage tool call confirmation with a single line of configuration when building the chat client.&lt;/p&gt;
    &lt;/li&gt;
    
    &lt;li&gt;
        &lt;p&gt;
            &lt;strong&gt;Confirmation UI&lt;/strong&gt;
            &lt;br&gt;
            Displays the dialog used to confirm tool calls.
        &lt;/p&gt;
    &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id="manage-tool-calls"&gt;Manage Tool Calls (IToolCallFilter)&lt;/h2&gt;

&lt;p&gt;The heart of our confirmation system is the &lt;code&gt;IToolCallFilter&lt;/code&gt; interface - an interface which defines how the chat intercepts and manages function calls.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-csharp"&gt;
public interface IToolCallFilter {
    public event Action&amp;lt;FunctionInvocationContext, TaskCompletionSource&amp;lt;bool&amp;gt;&amp;gt; ToolCalled;

    Task&amp;lt;bool&amp;gt; InvokeFunctionFilter(FunctionInvocationContext context);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;MyToolCallFilter&lt;/code&gt; manages AI-triggered actions and executes&amp;nbsp;sensitive operations only when&amp;nbsp;approved. The API design allows the filter to pause function execution, await user input, and continue or cancel based on the user&amp;#39;s decision. A &lt;code&gt;TaskCompletionSource&amp;lt;bool&amp;gt;&lt;/code&gt; instance enables asynchronous communication between the UI and filter logic.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-csharp"&gt;
public class MyToolCallFilter : IToolCallFilter {
    public event Action&amp;lt;FunctionInvocationContext, TaskCompletionSource&amp;lt;bool&amp;gt;&amp;gt; ToolCalled;

    public Task&amp;lt;bool&amp;gt; InvokeFunctionFilter(FunctionInvocationContext context) {
        if (ToolCalled is null)
            return Task.FromResult(true);

        var tcs = new TaskCompletionSource&amp;lt;bool&amp;gt;();
        ToolCalled.Invoke(context, tcs);
        return tcs.Task;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id="chat-client-confirm-tool-calls"&gt;Confirm Tool Calls (CustomFunctionInvokingChatClient)&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;CustomFunctionInvokingChatClient&lt;/code&gt; class extends our Blazor AI Chat control&amp;#39;s default behavior:&amp;nbsp;&lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;
        Intercepts AI tool calls (defines a custom &lt;code&gt;FunctionInvoker&lt;/code&gt; delegate).
    &lt;/li&gt;
    &lt;li&gt;
    	Checks for confirmation logic (whether the filter has been registered in the service collection).
    &lt;/li&gt;
    &lt;li&gt;
    	Proceeds with user approval. If the user cancels the request, the &lt;code&gt;CustomFunctionInvoker&lt;/code&gt;&amp;nbsp;method call returns a cancellation message instead of executing the tool. The message tells the LLM that the operation was aborted and that the requested information is unavailable.
    &lt;/li&gt;
&lt;/ul&gt;
    
&lt;pre&gt;&lt;code class="language-csharp"&gt;
public class CustomFunctionInvokingChatClient : FunctionInvokingChatClient {
    public CustomFunctionInvokingChatClient(IChatClient innerClient, ILoggerFactory? factory = null,
        IServiceProvider? services = null)
        : base(innerClient, factory, services) {
        if(services == null) {
            throw new ArgumentNullException(nameof(services), &amp;quot;Service provider cannot be null.&amp;quot;);
        }
        FunctionInvoker = CustomFunctionInvoker;
    }

    private async ValueTask&amp;lt;object?&amp;gt; CustomFunctionInvoker(FunctionInvocationContext context,
        CancellationToken cancellationToken) {
        IToolCallFilter? filter = FunctionInvocationServices!.GetService&amp;lt;IToolCallFilter&amp;gt;();

        if(await (filter?.InvokeFunctionFilter(context) ?? Task.FromResult(true))) {
            return await context.Function.InvokeAsync(context.Arguments, cancellationToken);
        }

        return &amp;quot;The tool call was cancelled by the user. Do not attempt to invoke this tool again. Return a message indicating that the call was cancelled and that the weather information is unavailable at this time.&amp;quot;;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id="create-confirmation-ui"&gt;Create the Confirmation UI&lt;/h2&gt;

&lt;p&gt;The confirmation dialog displays details about the pending tool call, including tool name, description, and arguments. A user can verify the tool call and ensure that retrieved arguments match the request. &lt;strong&gt;Confirm&lt;/strong&gt; and &lt;strong&gt;Cancel&lt;/strong&gt; buttons allow the user to approve or cancel the operation.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-html"&gt;
@if(_pendingTcs != null) {
    &amp;lt;div&amp;gt;
        @if(_pendingContext != null) {
            &amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;Please confirm the tool call.&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;
            &amp;lt;blockquote&amp;gt;
                &amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;Tool Called:&amp;lt;/strong&amp;gt; @_pendingContext.Function.Name&amp;lt;/p&amp;gt;
                &amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;Description:&amp;lt;/strong&amp;gt; @_pendingContext.Function.Description&amp;lt;/p&amp;gt;
            &amp;lt;/blockquote&amp;gt;
            &amp;lt;blockquote&amp;gt;
                &amp;lt;strong&amp;gt;Arguments:&amp;lt;/strong&amp;gt;
                &amp;lt;ul&amp;gt;
                    @foreach(var arg in _pendingContext.Arguments) {
                        &amp;lt;li&amp;gt;&amp;lt;strong&amp;gt;@arg.Key&amp;lt;/strong&amp;gt;: @arg.Value&amp;lt;/li&amp;gt;
                    }
                &amp;lt;/ul&amp;gt;
            &amp;lt;/blockquote&amp;gt;
        }

        &amp;lt;DxButton Text=&amp;quot;Confirm&amp;quot;
                  RenderStyle=&amp;quot;ButtonRenderStyle.Success&amp;quot;
                  IconCssClass=&amp;quot;oi oi-check&amp;quot;
                  Click=&amp;quot;() =&amp;gt; OnDecisionMade(true)&amp;quot; /&amp;gt;
        &amp;lt;DxButton Text=&amp;quot;Cancel&amp;quot;
                  RenderStyle=&amp;quot;ButtonRenderStyle.Secondary&amp;quot;
                  IconCssClass=&amp;quot;oi oi-x&amp;quot;
                  Click=&amp;quot;() =&amp;gt; OnDecisionMade(false)&amp;quot; /&amp;gt;
    &amp;lt;/div&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The following code implements confirmation workflow. The &lt;code&gt;ConfirmationButtons&lt;/code&gt; component subscribes to the &lt;code&gt;ToolCalled&lt;/code&gt; event exposed by &lt;code&gt;IToolCallFilter&lt;/code&gt;. When AI Chat attempts to invoke a tool, the filter fires this event and passes in a &lt;code&gt;FunctionInvocationContext&lt;/code&gt; and a &lt;code&gt;TaskCompletionSource&amp;lt;bool&amp;gt;&lt;/code&gt; that awaits the user&amp;#39;s decision.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-csharp"&gt;
@code {
    private FunctionInvocationContext? _pendingContext;
    private TaskCompletionSource&amp;lt;bool&amp;gt;? _pendingTcs;
    [Inject] IToolCallFilter? ToolCallFilter { get; set; }

    protected override void OnInitialized() {
        if(ToolCallFilter != null) {
            ToolCallFilter.ToolCalled += OnFunctionInvoked;
        }
    }

    private void OnFunctionInvoked(FunctionInvocationContext context, TaskCompletionSource&amp;lt;bool&amp;gt; tcs) {
        _pendingContext = context;
        _pendingTcs = tcs;
        StateHasChanged();
    }

    private void OnDecisionMade(bool decision) {
        _pendingTcs!.SetResult(decision);
        _pendingContext = null;
        _pendingTcs = null;
    }

    public void Dispose() {
        if(ToolCallFilter != null) {
            ToolCallFilter.ToolCalled -= OnFunctionInvoked;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id="integration-with-the-blazor-ai-chat-component"&gt;Integrate Confirmation UI with Blazor AI Chat&lt;/h2&gt;

&lt;p&gt;The chat displays the confirmation dialog whenever the LLM is about to execute a tool. The &lt;code&gt;MessageContentTemplate&lt;/code&gt; renders the confirmation dialog while the chat is in a &amp;quot;typing&amp;quot; state (indicating that the tool call is being processed).&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-html"&gt;
&amp;lt;DxAIChat CssClass=&amp;quot;main-content&amp;quot;&amp;gt;
    &amp;lt;MessageContentTemplate Context=&amp;quot;context&amp;quot;&amp;gt;
        @context.Content
        @if(context.Typing) {
            &amp;lt;ConfirmationButtons /&amp;gt;
        }
    &amp;lt;/MessageContentTemplate&amp;gt;
&amp;lt;/DxAIChat&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id="service-registration"&gt;Register Services&lt;/h2&gt;

&lt;p&gt;In &lt;i&gt;Program.cs&lt;/i&gt;, register &lt;code&gt;MyToolCallFilter&lt;/code&gt; and &lt;code&gt;IChatClient&lt;/code&gt; within the dependency injection (DI) container for each user session:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-csharp"&gt;
// Register the tool call filter
builder.Services.AddScoped&amp;lt;IToolCallFilter, MyToolCallFilter&amp;gt;();

// Configure the chat client with the confirmation layer
builder.Services.AddScoped(x =&amp;gt; {
    return new ChatClientBuilder(azureChatClient)
        .ConfigureOptions(x =&amp;gt; {
            x.Tools = [CustomAIFunctions.GetWeatherTool];
        })
        .UseMyToolCallConfirmation()
        .Build(x);
});

builder.Services.AddDevExpressAI();
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id="fluent-api-extension"&gt;Fluent API Extension&lt;/h2&gt;

&lt;p&gt;A fluent API extension allows you to activate tool call confirmation with a single method call in your chat client configuration:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-csharp"&gt;
public static class CustomFunctionInvokingChatClientExtensions {
    public static ChatClientBuilder UseMyToolCallConfirmation(this ChatClientBuilder builder,
        ILoggerFactory? loggerFactory = null) {
        return builder.Use((innerClient, services) =&amp;gt; {
            loggerFactory ??= services.GetService&amp;lt;ILoggerFactory&amp;gt;();
            return new CustomFunctionInvokingChatClient(innerClient, loggerFactory, services);
        });
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id="user-experience-in-action"&gt;User Experience in Action&lt;/h2&gt;

&lt;p&gt;When a user requests weather information, the following sequence occurs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The LLM identifies that a function call is required.&lt;/li&gt;
&lt;li&gt;A confirmation dialog is displayed (instead of executing immediately).&lt;/li&gt;
&lt;li&gt;The confirmation dialog displays tool name, description, and retrieved arguments.&lt;/li&gt;
&lt;li&gt;The user can approve or cancel the operation&lt;/li&gt;
&lt;li&gt;Only approved tools are executed (their results are returned to the LLM).&lt;/li&gt;
&lt;/ol&gt;



&lt;video controls=""&gt;
    &lt;source src="https://community.devexpress.com/blogs/aspnet/25.2/ai-tool-call-confirm/blazor-ai-chat-tool-calling-confirmation_square.mp4" type="video/mp4"&gt;
    Your browser does not support the video tag.
&lt;/video&gt;

&lt;h2 id="advanced-customization-options"&gt;Advanced Customization Options&lt;/h2&gt;

&lt;h3 id="selective-tool-call-confirmation"&gt;Selective Tool Call Confirmation&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;SelectiveToolCallFilter&lt;/code&gt; extends &lt;code&gt;IToolCallFilter&lt;/code&gt; to require user confirmation before calling tools designed to execute&amp;nbsp;sensitive operations (such as deleting data, sending emails, or processing payments):&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-csharp"&gt;
public class SelectiveToolCallFilter : IToolCallFilter {
    private readonly string[] _sensitiveOperations = { &amp;quot;DeleteData&amp;quot;, &amp;quot;SendEmail&amp;quot;, &amp;quot;ChargePayment&amp;quot; };

    public Task&amp;lt;bool&amp;gt; InvokeFunctionFilter(FunctionInvocationContext context) {
        // Only require confirmation for sensitive operations
        if (!_sensitiveOperations.Contains(context.Function.Name)) {
            return Task.FromResult(true);
        }

        // Show confirmation for sensitive operations
        if (ToolCalled is null)
            return Task.FromResult(true);

        var tcs = new TaskCompletionSource&amp;lt;bool&amp;gt;();
        ToolCalled.Invoke(context, tcs);
        return tcs.Task;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id="enhanced-ui-styling"&gt;Enhanced Confirmation UI&lt;/h3&gt;
&lt;p&gt;
    Modify the &lt;i&gt;ConfirmationButtons.razor&lt;/i&gt; component to create a confirmation dialog based on UI requirements. You can modify the layout, apply custom styles, and inform users about the tool they are about to execute.
&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-csharp"&gt;
&amp;lt;div class=&amp;quot;tool-confirmation-container&amp;quot;&amp;gt;
    &amp;lt;div class=&amp;quot;confirmation-header&amp;quot;&amp;gt;
        &amp;lt;h5&amp;gt;⚠️ Function Execution Request&amp;lt;/h5&amp;gt;
    &amp;lt;/div&amp;gt;

    &amp;lt;div class=&amp;quot;function-details&amp;quot;&amp;gt;
        &amp;lt;div class=&amp;quot;detail-row&amp;quot;&amp;gt;
            &amp;lt;span class=&amp;quot;label&amp;quot;&amp;gt;Function:&amp;lt;/span&amp;gt;
            &amp;lt;span class=&amp;quot;value&amp;quot;&amp;gt;@_pendingContext.Function.Name&amp;lt;/span&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div class=&amp;quot;detail-row&amp;quot;&amp;gt;
            &amp;lt;span class=&amp;quot;label&amp;quot;&amp;gt;Description:&amp;lt;/span&amp;gt;
            &amp;lt;span class=&amp;quot;value&amp;quot;&amp;gt;@_pendingContext.Function.Description&amp;lt;/span&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;

    &amp;lt;div class=&amp;quot;arguments-section&amp;quot;&amp;gt;
        &amp;lt;h6&amp;gt;Arguments:&amp;lt;/h6&amp;gt;
        @foreach(var arg in _pendingContext.Arguments) {
            &amp;lt;div class=&amp;quot;argument-item&amp;quot;&amp;gt;
                &amp;lt;strong&amp;gt;@arg.Key:&amp;lt;/strong&amp;gt; @arg.Value
            &amp;lt;/div&amp;gt;
        }
    &amp;lt;/div&amp;gt;

    &amp;lt;div class=&amp;quot;action-buttons&amp;quot;&amp;gt;
        &amp;lt;DxButton Text=&amp;quot;Approve&amp;quot;
                  RenderStyle=&amp;quot;ButtonRenderStyle.Success&amp;quot;
                  Click=&amp;quot;() =&amp;gt; OnDecisionMade(true)&amp;quot; /&amp;gt;
        &amp;lt;DxButton Text=&amp;quot;Deny&amp;quot;
                  RenderStyle=&amp;quot;ButtonRenderStyle.Danger&amp;quot;
                  Click=&amp;quot;() =&amp;gt; OnDecisionMade(false)&amp;quot; /&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id="enhanced-ui-styling"&gt;Audit Trail&lt;/h3&gt;

&lt;p&gt;Log user decisions with relevant details (such as tool name, function arguments, timestamp, and user role):&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-csharp"&gt;
public class AuditingToolCallFilter : IToolCallFilter {
    private readonly ILogger&amp;lt;AuditingToolCallFilter&amp;gt; _logger;
 
    public AuditingToolCallFilter(ILogger&amp;lt;AuditingToolCallFilter&amp;gt; logger) {
        _logger = logger;
    }

    public event Action&amp;lt;FunctionInvocationContext, TaskCompletionSource&amp;lt;bool&amp;gt;&amp;gt;? ToolCalled;
    public Task&amp;lt;bool&amp;gt; InvokeFunctionFilter(FunctionInvocationContext context)
    {
        if (ToolCalled is null)
            return Task.FromResult(true);

        var tcs = new TaskCompletionSource&amp;lt;bool&amp;gt;();
        
        // Subscribe to the task completion to log the decision
        tcs.Task.ContinueWith(task =&amp;gt; {
            if (task.IsCompletedSuccessfully)
            {
                OnDecisionMade(task.Result, context);
            }
        }, TaskContinuationOptions.ExecuteSynchronously);

        ToolCalled.Invoke(context, tcs);
        return tcs.Task;
    }
 
    private void OnDecisionMade(bool decision, FunctionInvocationContext context) {
        _logger.LogInformation(&amp;quot;User {Decision} function call: {FunctionName} with args: {Arguments}&amp;quot;,
            decision ? &amp;quot;approved&amp;quot; : &amp;quot;denied&amp;quot;,
            context.Function.Name,
            string.Join(&amp;quot;, &amp;quot;, context.Arguments.Select(a =&amp;gt; $&amp;quot;{a.Key}={a.Value}&amp;quot;)));
 
        // Send decision data to the analytics service
        // TrackUserDecision(decision, context);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id="security-considerations"&gt;Security Considerations&lt;/h2&gt;

&lt;p&gt;The confirmation UI enhances function calling transparency and user control. To strengthen security alongside the confirmation UI, implement the following measures:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Rate Limiting&lt;/strong&gt;: Restrict the number of tool calls per user or session.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Permission Checks&lt;/strong&gt;: Verify user permissions before displaying the confirmation dialog.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Function Validation&lt;/strong&gt;: Validate function arguments before execution.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Audit Trails&lt;/strong&gt;: Log all tool calls and user decisions for monitoring and compliance.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Timeout Handling&lt;/strong&gt;: Automatically deny tool execution if the user does not respond within a predefined period of time.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id="download-the-complete-example"&gt;Download the Example&lt;/h2&gt;

&lt;p&gt;The full source code for this implementation is available on &lt;a target="_blank" href="https://github.com/DevExpress-Examples/blazor-ai-chat-confirm-tool-calls"&gt;GitHub&lt;/a&gt;. Clone the repo and follow the instructions to setup your tool call confirmation system.&lt;/p&gt;

&lt;h2 id="your-feedback-counts-"&gt;Your Feedback Counts!&lt;/h2&gt;
&lt;p&gt;This tool call confirmation system demonstrates one approach to balancing AI automation with user control. We&amp;#39;re considering including similar functionality as a built-in feature in future versions of the DevExpress Blazor AI Chat component.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In the meantime, we&amp;#39;d love to hear your thoughts on this implementation:&lt;/strong&gt;&lt;/p&gt;&lt;div data-survey-id="9c4ba6e3-97da-497c-9690-ac353fee6630" data-survey-auth-required="false"&gt;&lt;/div&gt;</description>
      <pubDate>Mon, 18 Aug 2025 01:35:00 Z</pubDate>
      <dc:creator>Dmitry Tokmachev (DevExpress)</dc:creator>
    </item>
    <item>
      <guid isPermaLink="false">bd716303-653c-428d-8b8a-a7d998cde032:388256</guid>
      <link>https://community.devexpress.com/Blogs/aspnet/archive/2025/08/13/blazor-year-end-roadmap-v25-2.aspx</link>
      <category domain="https://community.devexpress.com/Tags/2025">2025</category>
      <category domain="https://community.devexpress.com/Tags/Blazor">Blazor</category>
      <category domain="https://community.devexpress.com/Tags/Featured">Featured</category>
      <category domain="https://community.devexpress.com/Tags/Roadmap">Roadmap</category>
      <category domain="https://community.devexpress.com/Tags/Survey">Survey</category>
      <category domain="https://community.devexpress.com/Tags/v25.2">v25.2</category>
      <title>Blazor — Year-End Roadmap (v25.2)</title>
      <description>&lt;div class="Note"&gt;The information contained within this blog post details our current/projected development plans. Please note that this information is being shared for INFORMATIONAL PURPOSES ONLY and does not represent a binding commitment on the part of Developer Express Inc. This blog post and the features/products listed within it are subject to change. You should not rely or use this information to help make a purchase decision about Developer Express Inc products.&lt;/div&gt;

&lt;h2 id="live-roadmap-updates"&gt;Roadmap Updates&lt;/h2&gt;
&lt;p&gt;Our year-end Blazor roadmap will be updated regularly to reflect development progress. As we get closer to the release, we expect to add additional&amp;nbsp;items and modify the status of planned features. Look for the following labels next to every feature:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;p class="tags"&gt;&lt;span class="not-started"&gt;Planned&lt;/span&gt; — Feature is scheduled but not yet in development.&lt;/p&gt;&lt;/li&gt;
    &lt;li&gt;&lt;p class="tags"&gt;&lt;span class="development"&gt;In Development&lt;/span&gt; — Under active development.&lt;/p&gt;&lt;/li&gt;
    &lt;li&gt;&lt;p class="tags"&gt;&lt;span class="completed"&gt;Coming in EAP v25.2&lt;/span&gt; — Will be available in our first v25.2 early access preview.&lt;/p&gt;&lt;/li&gt;
    &lt;li&gt;&lt;p class="tags"&gt;&lt;span class="completed"&gt;Coming in v25.2&lt;/span&gt; — Will be included in the final v25.2 release.&lt;/p&gt;&lt;/li&gt;
    &lt;li&gt;&lt;p class="tags"&gt;&lt;span class="completed"&gt;Released in v25.2&lt;/span&gt; — Fully implemented and available.&lt;/p&gt;&lt;/li&gt;
    
&lt;/ul&gt;
&lt;h2 id="-net-10-support"&gt;.NET 10 Support&lt;/h2&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Released in v25.2&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;DevExpress Blazor UI components will support .NET 10 following Microsoft’s official release. Preview builds will be available for early adopters.&lt;/p&gt;
&lt;h2 id="content-security-policy-csp-enhancements"&gt;Content Security Policy (CSP) Enhancements&lt;/h2&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Released in v25.2&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We plan to enhance Content Security Policy (CSP) support across our Blazor component suite. DevExpress Blazor components will no longer require the &lt;code&gt;unsafe-inline&lt;/code&gt; style source.&lt;/p&gt;
&lt;h2 id="accessibility-enhancements"&gt;Accessibility Enhancements&lt;/h2&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Released in v25.2&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Improvements/updates for&amp;nbsp;Data Editors&lt;/li&gt;
&lt;li&gt;Screen reader support for the Rich Text Editor&lt;/li&gt;
&lt;li&gt;Better keyboard support for Popup, DropDown, and Window components&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;DevExpress MCP Server for AI-Powered Documentation Access&lt;/h2&gt;
&lt;p class="tags"&gt;
    &lt;span class="completed"&gt;&lt;a target="_blank" href="https://docs.devexpress.com/GeneralInformation/405551/help-resources/dev-express-documentation-mcp-server-configure-an-ai-powered-assistant"&gt;Available in Preview&lt;/a&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;We will introduce an MCP server that connects GitHub Copilot Chat, Cursor, and other MCP-compatible AI tools directly to our comprehensive documentation database. The server will provide instant access to over 300,000 help topics through natural language queries within your IDE. This will allow you and AI coding agents such as Claude Code to access current DevExpress documentation directly within the AI assistant&amp;#39;s context.&lt;/p&gt;
&lt;img src="https://community.devexpress.com/blogs/winforms/20251008-Win-Roadmap-252/dx-mcp-docs-assistant.png" alt="" style="width:862px;height:391px;"&gt;
&lt;h2 id="focus-on-performance"&gt;A Focus on Performance&lt;/h2&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Released in v25.2&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We recently introduced significant performance improvements across our Blazor component suite (see &lt;a href="https://www.devexpress.com/subscriptions/whats-new/#blazor-performance-enhancements"&gt;v25.1 release notes&lt;/a&gt; for additional information). In v25.2, we will extend our performance optimizations with new&amp;nbsp;enhancements. We will update this post with additional information as we get closer to release.&amp;nbsp;&lt;/p&gt;
&lt;h3 id="grid-treelist-filter-menu-faster-dropdown-opening"&gt;Blazor Grid &amp;amp; TreeList Filter Menu — Improved Dropdown Responsiveness&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Released in v25.2&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We will&amp;nbsp;optimize rendering speed and improve responsiveness for column filter menus used within our Blazor Grid and TreeList components.&lt;/p&gt;
&lt;h2 id="blazor-project-templates-new-sample-views"&gt;Blazor Project Templates — New Sample Views&lt;/h2&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Released in v25.2&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The primary Blazor template in our Template Kit will be able to add sample views for complex component libraries (Blazor Charts, Reporting, Scheduler, and AI Chat). &lt;/p&gt;
&lt;img src="https://community.devexpress.com/blogs/aspnet/25.2/Roadmap/Blazor%20Project%20Templates%20—%20New%20Sample%20Views.png" alt="New Sample Views"&gt;
&lt;h2 id="new-blazor-smart-autocomplete"&gt;New Blazor Smart Autocomplete&lt;/h2&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Released in v25.2&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We expect to introduce Smart Autocomplete, a new AI-powered Extension designed to accelerate text input. Smart Autocomplete connects to our Blazor Memo and displays gray inline suggestions based on current input. Suggestions appear seamlessly within the Blazor Memo Editor without interrupting typing flow. Users can accept a suggestion or simply continue typing to dismiss it.&lt;/p&gt;
&lt;img src="https://community.devexpress.com/blogs/aspnet/25.2/Roadmap/Blazor%20AI%20Autocomplete.gif.gif" class="small" style="width:542px;height:426px;" alt="AI Smart Autocomplete"&gt;
&lt;h2 id="blazor-ai-chat"&gt;Blazor AI Chat&lt;/h2&gt;
&lt;h3 id="tool-api"&gt;Tool API&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Released in v25.2&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;New APIs will allow you to create tools that execute any custom command (apply filters to Grids, modify Chart UI, query databases, or perform business actions). With these tools, users will be able to interact with your DevExpress-powered application directly from AI Chat using natural language.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;[AIIntegrationTool(&amp;quot;DxGrid_SetGridFilter&amp;quot;)]
[Description(&amp;quot;Applies a filter to the specified DxGrid component using a DevExpress Criteria Language filter string. This changes the UI to display only rows matching the given criteria.&amp;quot;)]
public static object SetGridFilter(
        [Description(&amp;quot;The DxGrid component to apply the filter to.&amp;quot;)]
        DxGrid grid,
        [Description(&amp;quot;The filter criteria string in DevExpress Criteria Language Syntax. Example: \&amp;quot;[Status] = &amp;#39;Active&amp;#39; AND [HireDate] &amp;gt; #2020-01-01#\&amp;quot;.&amp;quot;)]
        string filter) {
    grid.SetFilterCriteria(CriteriaOperator.Parse(filter ?? string.Empty));
    int visibleRowCount = grid.GetVisibleRowCount();
    return new { success = true, visibleRowCount };
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id="tool-call-visualization"&gt;Tool Call Visualization&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Released in v25.2&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The DevExpress Blazor AI Chat control will clearly indicate when it executes tools (declared locally within the app or available via MCP servers). This will increase clarity and transparency and will help users understand what actions are being performed.&lt;/p&gt;
&lt;img src="https://community.devexpress.com/blogs/aspnet/25.2/Roadmap/Blazor%20AI%20Chat%20–%20Tool%20Call%20Visualization.png" alt="Tool Call Visualization"&gt;
&lt;div class="Note"&gt;
    &lt;p&gt;Learn more about this feature and take part in our survey:&amp;nbsp;&lt;a href="https://community.devexpress.com/Blogs/aspnet/archive/2025/08/18/devexpress-blazor-ai-chat-tool-call-confirmation.aspx" target="_blank"&gt;DevExpress Blazor AI Chat — Tool Call Confirmation&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;h3 id="resources"&gt;Resources&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Released in v25.2&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We will introduce a resources feature for our Blazor AI Chat control, allowing users to attach additional context to their chat messages. Unlike file attachments, resources can include files or other types of context supplied by the application (binary files including audio, images and PDFs, database schemas, records, logs, etc). Users will be able to view available resources in a dedicated UI element and attach them to their chat context.&lt;/p&gt;
&lt;h3 id="resizing-for-input-area"&gt;Resizing for Input Area&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Released in v25.2&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Users will be able to resize the chat input area to fit large prompt messages.&lt;/p&gt;
&lt;img src="https://community.devexpress.com/blogs/aspnet/25.2/Roadmap/Blazor%20AI%20Chat%20–%20Resizing%20for%20Input%20Area.png" alt="Resizing for Input Area"&gt;
&lt;h2 id="blazor-grid-treelist"&gt;Blazor Grid &amp;amp; TreeList&lt;/h2&gt;
&lt;h3 id="column-virtualization"&gt;Column Virtualization&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Released in v25.2&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;As you may know, our Blazor Grid and TreeList support row virtualization. In our next major release (v25.2), we plan to extend this capability and support column virtualization. With this feature enabled, the DevExpress Grid and TreeList will only render columns within the current viewport. This will reduce DOM size and ensure fast rendering even for tables with hundreds of columns.&lt;/p&gt;
&lt;h3 id="integrated-filter-builder"&gt;Integrated Filter Builder&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Released in v25.2&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;In our year-end release, we plan to integrate our Filter Builder control directly into the Blazor Grid and TreeList. This integration will reduce the amount of code required to configure filter fields and streamline the process associated with complex filter conditions.&lt;/p&gt;
&lt;p&gt;We also expect to synchronize the Filter Builder, Filter Row, and Filter Menus within the same component. Users will be able to view/modify all active filters from a single, centralized UI.&lt;/p&gt;
&lt;img src="https://community.devexpress.com/blogs/aspnet/25.2/Roadmap/Blazor%20Grid%20&amp;amp;%20TreeList%20–%20Integrated%20Filter%20Builder.png" alt="Integrated Filter Builder"&gt;
&lt;h3 id="command-column-icons"&gt;Command Column Icons&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Released in v25.2&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;With v25.2, the DevExpress Blazor&amp;nbsp;Grid and TreeList will display built-in icons for command actions by default. This change will help reduce column width and provide a cleaner, more modern appearance.&lt;/p&gt;
&lt;img src="https://community.devexpress.com/blogs/aspnet/25.2/Roadmap/Blazor%20Grid%20&amp;amp;%20TreeList%20–%20New%20Built-in%20Command%20Column%20Action%20Buttons.png" alt="New Built-in Command Column Action Buttons"&gt;
&lt;h3 id="vertical-grid-line-visibility"&gt;Vertical Grid Line Visibility&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="development"&gt;Postponed to v26.1&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We will add an option to hide column lines (vertical separators between adjacent columns) in our Blazor Grid and TreeList components.&lt;/p&gt;
&lt;p&gt;This change is part of our ongoing effort to deliver a cleaner and more modern UI.&lt;/p&gt;
&lt;img src="https://community.devexpress.com/blogs/aspnet/25.2/Roadmap/Blazor%20Grid%20&amp;amp;%20TreeList%20–%20Column%20Lines%20Visibility%20Customization.png" alt="Column Lines Visibility Customization"&gt;
&lt;h2 id="blazor-grid"&gt;Blazor Grid&lt;/h2&gt;
&lt;h3 id="context-menu"&gt;Context Menu&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Released in v25.2&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We plan to introduce a built-in context menu for the Blazor Grid component. Our context menu will include a predefined set of actions for each Grid region and allow you to define/customize items. Supported regions will include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Row&lt;/li&gt;
&lt;li&gt;Group Row&lt;/li&gt;
&lt;li&gt;Column&lt;/li&gt;
&lt;li&gt;Footer&lt;/li&gt;
&lt;li&gt;Group panel&lt;/li&gt;
&lt;li&gt;Group footer&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We also plan to include a set of built-in actions for the column region to simplify common operations.&lt;/p&gt;
&lt;img src="https://community.devexpress.com/blogs/aspnet/25.2/Roadmap/Blazor%20Grid%20–%20Context%20Menu.png" alt="Context Menu"&gt;
&lt;h2 id="blazor-data-editors"&gt;Blazor Data Editors&lt;/h2&gt;
&lt;h3 id="blazor-tagbox-keyboard-navigation-enhancements"&gt;Blazor TagBox — Keyboard Navigation Enhancements&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Released in v25.2&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Users will be able to focus individual tags, making it easier to manage tag collections using only the keyboard (e.g., to delete a specific tag).&lt;/p&gt;
&lt;h3 id="date-edit-time-edit-time-selection-ui-redesign"&gt;Date Edit &amp;amp; Time Edit — Time Selection UI Redesign&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Released in v25.2&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We will rework the popup UI for our Date Edit and Time Edit components to improve usability and make the Accept/Cancel buttons more visible.&lt;/p&gt;
&lt;p&gt;As part of this update, the Clear button will also be removed from the popup and will only remain in the edit box. To clear the editor value, users will be able to execute the new Alt+Del shortcut (like our ComboBox editor).&lt;/p&gt;
&lt;img src="https://community.devexpress.com/blogs/aspnet/25.2/Roadmap/Blazor%20Data%20Editors%20–%20Date%20Edit%20&amp;amp;%20Time%20Edit%20—%20Time%20Selection%20UI%20Redesign.png" alt="Time Selection UI Redesign"&gt;
&lt;h3 id="blazor-memo-adaptive-height-support"&gt;Blazor Memo — Adaptive Height Support&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Released in v25.2&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Our Blazor Memo will be able to auto-adjust height based on content (to display text without scrolling).&lt;/p&gt;

&lt;h2 id="filter-builder-official-release"&gt;Filter Builder — Official Release&lt;/h2&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Released in v25.2&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The Filter Builder component (introduced as a CTP in v25.1) will be ready for production use in v25.2. Planned new features/enhancements:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Keyboard navigation and accessibility (a11y) support&lt;/li&gt;
&lt;li&gt;Improved localization&lt;/li&gt;

&lt;li&gt;Direct integration with the Grid, eliminating the need to configure the Filter Builder separately&lt;/li&gt;
&lt;li&gt;Expanded customization API with support for additional templates and configurable filter operators&lt;/li&gt;
&lt;li&gt;Enhanced performance for large data objects&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="blazor-pivot-table-official-release"&gt;Blazor Pivot Table — Official Release&lt;/h2&gt;
&lt;p&gt;In v25.1, we shipped a number of essential Pivot Table-related features, including API and UI-based filtering, field reordering, persistent layout support, and a built-in field list.&lt;/p&gt;
&lt;p&gt;We initially planned to announce the official release in v25.1. However, two key features — column virtualization and keyboard navigation, were not yet ready for production use, so we decided to postpone the official release announcement.&lt;/p&gt;
&lt;p&gt;With v25.2, we expect to officially ship the DevExpress Blazor Pivot Table control. We will conduct additional testing and apply final polish to ensure the component meets production-ready standards.&lt;/p&gt;
&lt;h3 id="keyboard-navigation"&gt;Keyboard Navigation&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Released in v25.2&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Users will be able to access every UI element in the DevExpress Blazor Pivot Table via the&amp;nbsp;keyboard. In addition, we plan to add keyboard shortcuts for the following actions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sorting&lt;/li&gt;
&lt;li&gt;Filtering&lt;/li&gt;
&lt;li&gt;Expanding/collapsing grouped values&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="column-virtualization"&gt;Column Virtualization&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Released in v25.2&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;To ensure optimal performance with large datasets, our Blazor Pivot Table already supports row virtualization. In v25.2, we plan to extend this functionality by adding column virtualization.&lt;/p&gt;
&lt;p&gt;This feature is essential when the Pivot Table displays a large&amp;nbsp;number of columns — for example, when displaying one column per day across an entire year. Column virtualization will allow the component to render visible columns, significantly reducing DOM size and improving responsiveness.&lt;/p&gt;
&lt;p&gt;As part of this effort, we will perform extensive internal testing to verify performance and stability in high density scenarios. Our goal is to ensure reliable operation when working with horizontally large datasets.&lt;/p&gt;
&lt;h2 id="blazor-ribbon"&gt;Blazor Ribbon&lt;/h2&gt;
&lt;h3 id="official-release"&gt;Official Release&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Released in v25.2&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The single-line Ribbon component, previously available as a CTP, will be officially released and ready for production use in v25.2. Planned enhancements include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Visual improvements, including a redesigned overflow menu with item groups, scrolling support, and a more polished appearance&lt;/li&gt;
&lt;li&gt;Extended APIs for Ribbon items&lt;/li&gt;
&lt;li&gt;Keyboard navigation and accessibility (a11y) support&lt;/li&gt;
&lt;li&gt;Reworked adaptivity logic for better responsiveness&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="rich-text-editor-and-html-editor-integration"&gt;Rich Text Editor and HTML Editor Integration&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Released in v25.2&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Our Rich Text Editor and HTML Editor components will use the new Ribbon internally and will benefit from its enhanced visuals, reworked adaptivity, and extensive customization options.&lt;/p&gt;
&lt;h2 id="blazor-scheduler"&gt;Blazor Scheduler&lt;/h2&gt;
&lt;h3 id="timeline-view-more-compact-cell-height"&gt;Timeline View — More Compact Cell Height&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Released in v25.2&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Currently, cell height in the Scheduler Timeline view cannot be less than 150 pixels. In v25.2, we plan to remove minimum cell height restrictions and calculate it based on appointment size. This change will help you to create more compact interfaces and maximize screen real-estate.&lt;/p&gt;
&lt;img src="https://community.devexpress.com/blogs/aspnet/25.2/Roadmap/Blazor%20Scheduler%20–%20Timeline%20View%20—%20More%20Compact%20Cell%20Height.png" alt="More Compact Cell Height"&gt;
&lt;h3 id="ui-ux-enhancements"&gt;UI/UX Enhancements&lt;/h3&gt;
&lt;h4 id="time-cells-appointment-hover-effect"&gt;Time Cells &amp;amp; Appointment Hover Effect&lt;/h4&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Released in v25.2&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;p&gt;In our year-end release, we expect to introduce a new hover effect for both empty cells and appointments:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;For an empty area, the hover effect will suggest to create a new appointment&lt;/li&gt;
&lt;li&gt;For existing appointments, the hover effect will signal that the item can be edited or resized.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The hover effect will improve perceived responsiveness by indicating that a hovered element is interactive. It will not appear if appointment creation or editing is disabled.&lt;/p&gt;
&lt;img src="https://community.devexpress.com/blogs/aspnet/25.2/Roadmap/Empty%20Cells%20and%20Appointment%20Hover%20Effect.gif" alt="Empty Cells and Appointment Hover Effect"&gt;
&lt;h4 id="appointment-tooltip-edit-form-layout-changes"&gt;Appointment Tooltip &amp;amp; Edit Form Layout Changes&lt;/h4&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Released in v25.1.4&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We plan to introduce minor layout refinements to the Scheduler’s tooltip and edit form. These changes will improve visual structure, reduce unnecessary spacing, and contribute to a cleaner, more consistent UI.&lt;/p&gt;
&lt;img src="https://community.devexpress.com/blogs/aspnet/25.2/Roadmap/Blazor%20Scheduler%20–%20Appoitment’s%20Tooltip%20&amp;amp;%20Edit%20Form%20Layout%20Changes%20-%20After.png" alt="Appoitment’s Tooltip &amp;amp; Edit Form Layout Changes"&gt;
&lt;h2 id="blazor-themes"&gt;Blazor Themes&lt;/h2&gt;
&lt;h3 id="theme-api-current-theme"&gt;Theme API — Current Theme&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="development"&gt;Postponed to v26.1&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We will extend our theme APIs to allow developers to check which theme is currently applied.&lt;/p&gt;
&lt;h3 id="fluent-bootstrap-styles"&gt;Fluent — Bootstrap Styles&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Released in v25.1.4&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Fluent themes will include optional Bootstrap styles for the default color accent (blue) in both light and dark modes. You will be able to include them as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;@DxResourceManager.RegisterTheme(Themes.Fluent.Clone(properties =&amp;gt; {
    properties.UseBootstrapStyles = true;
}))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For styles dependent on Fluent accent colors, we recommend using DevExpress CSS variables instead. Due to Bootstrap&amp;#39;s CSS architecture, Bootstrap styles will not reflect your accent colors, so use them only for non-color customizations.&lt;/p&gt;
&lt;h3 id="fluent-public-css-variables"&gt;Fluent — Public CSS Variables&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Released in v25.2&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We will document global CSS variables available in Fluent. This documentation will help you customize Fluent themes or simply reference global variables in your own CSS.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-css"&gt;.my-card {
    position: relative;
    display: flex;
    flex-direction: column;
    min-width: 0;
    overflow-wrap: break-word;
    background-color: var(--DS-color-surface-neutral-default-rest);
    background-clip: border-box;
    border: var(--DS-border-radius-10) solid var(--DS-color-border-neutral-default-rest);
    border-radius: 0.25rem;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="blazor-reporting"&gt;Blazor Reporting&lt;/h2&gt;
&lt;p&gt;Learn more:&amp;nbsp;&lt;a href="https://community.devexpress.com/Blogs/reporting/archive/2025/08/13/devexpress-reports-amp-bi-dashboard-november-2025-roadmap-v25-2.aspx" target="_blank"&gt;DevExpress Reports &amp;amp; BI Dashboard — Year-End Roadmap (v25.2)&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="your-feedback"&gt;Your Feedback Matters&lt;/h2&gt;
&lt;div data-survey-id="98baf635-770a-4431-89f9-4408a5d37345" data-survey-auth-required="false"&gt;&lt;/div&gt;</description>
      <pubDate>Wed, 13 Aug 2025 08:30:00 Z</pubDate>
      <dc:creator>Alex Chuev (DevExpress)</dc:creator>
      <dx:excerpt>This post outlines key features/enhancements planned for our next major update (v25.2)</dx:excerpt>
    </item>
    <item>
      <guid isPermaLink="false">bd716303-653c-428d-8b8a-a7d998cde032:388247</guid>
      <link>https://community.devexpress.com/Blogs/aspnet/archive/2025/05/06/devexpress-blazor-ai-chat-build-a-multi-llm-chat-application.aspx</link>
      <category domain="https://community.devexpress.com/Tags/AI">AI</category>
      <category domain="https://community.devexpress.com/Tags/Blazor">Blazor</category>
      <category domain="https://community.devexpress.com/Tags/LLM">LLM</category>
      <title>DevExpress Blazor AI Chat — Build a Multi-LLM Chat Application </title>
      <description>&lt;p&gt; AI services offer a variety of models tailored to meet user needs, preferences, and resource constraints. As you&amp;#39;d expect, models have strengths/weaknesses — some are optimized for coding tasks, while others are better suited for creative writing or real-time information retrieval.&lt;/p&gt;
&lt;p&gt;To select the appropriate&amp;nbsp;model, you often need to balance performance and cost. For example, advanced models like GPT-4.1 deliver exceptional results but require greater computational resources. In contrast, lighter models such as GPT-4.1 Mini or Nano offer faster response and lower costs, making them ideal for those seeking efficiency and responsiveness.&lt;/p&gt;
&lt;p&gt;For enterprise applications, the ability to connect to a cloud-based AI service — with the option to fallback to offline models running in restricted environments — is often a must.&lt;/p&gt;
&lt;p&gt;In this post, I’ll show you how to build a multi-LLM (Large Language Model) chat application that uses &lt;strong&gt;DevExpress Blazor AI Chat&lt;/strong&gt; and &lt;strong&gt;ComboBox&lt;/strong&gt; components. You’ll learn how to implement the &lt;code&gt;IChatClient&lt;/code&gt; interface to manage multiple chat clients and their respective conversation histories (and how to use the DevExpress Blazor ComboBox to switch between LLMs during a chat session).&lt;/p&gt;
&lt;h2 id="getting-started"&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;To get started, you must first integrate the &lt;code&gt;DxAIChat&lt;/code&gt; component into your application (see our official guide for additional information in this regard): &lt;a target="_blank" href="https://docs.devexpress.com/Blazor/DevExpress.AIIntegration.Blazor.Chat.DxAIChat#add-an-ai-chat-to-a-project"&gt;Add AI Chat to a Project&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In this guide, I will use two LLMs: GPT-4o from Azure OpenAI and Phi4 from Ollama running locally. &lt;/p&gt;
&lt;p&gt;Here are my sample registrations for both chat clients from my&amp;nbsp;&lt;code&gt;Program.cs&lt;/code&gt; code unit. Note that I store LLM&amp;nbsp;credentials and settings in the app configuration file (&lt;code&gt;appSettings.Development.json&lt;/code&gt;). You can modify the following code to match your specific requirements:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;
using Azure;
using Azure.AI.OpenAI;
using Microsoft.Extensions.AI;
...
var openAiServiceSettings = builder.Configuration.GetSection(&amp;quot;OpenAISettings&amp;quot;).Get&amp;lt;OpenAIServiceSettings&amp;gt;();
var ollamaSettings = builder.Configuration.GetSection(&amp;quot;OllamaSettings&amp;quot;).Get&amp;lt;OllamaSettings&amp;gt;();

IChatClient azureChatClient = new AzureOpenAIClient(
    new Uri(openAiServiceSettings.Endpoint),
    new AzureKeyCredential(openAiServiceSettings.Key))
    .AsChatClient(openAiServiceSettings.DeploymentName);

IChatClient ollamaChatClient = new OllamaChatClient(
    new Uri(ollamaSettings.Uri), 
    ollamaSettings.ModelName);&lt;/code&gt;
&lt;/pre&gt;
&lt;div class="Note"&gt;
	&lt;p&gt;NOTE: To install, run, and download Ollama model, refer to the &lt;a target="_blank" href="https://docs.devexpress.com/CoreLibraries/405204/ai-powered-extensions#prerequisites"&gt;DevExpress AI Extensions — Prerequisities&lt;/a&gt; help topic. &lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Next, we will implement infrastructure designed to track each client and its history.&lt;/p&gt;
&lt;h2 id="compositechatclient-implementation"&gt;CompositeChatClient Implementation&lt;/h2&gt;
&lt;p&gt;First, declare the &lt;code&gt;ChatClientSession&lt;/code&gt; class that represents an individual LLM session (includes the user-friendly model/service name, a client instance, and message history):&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;
using Microsoft.Extensions.AI;
//...
public class ChatClientSession {
    public string Name { get; set; }
    public IChatClient Client { get; }
    public List&amp;lt;BlazorChatMessage&amp;gt; Messages { get; set; }

    public ChatClientSession(IChatClient client, string name) {
        Name = name;
        Client = client ?? throw new ArgumentNullException(nameof(client));
        Messages = new List&amp;lt;BlazorChatMessage&amp;gt;();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next,&amp;nbsp;define the &lt;code&gt;CompositeChatClient&lt;/code&gt; class, which implements the &lt;code&gt;IChatClient&lt;/code&gt; interface and serves as a container for multiple chat clients. By wrapping multiple clients within a single interface implementation, we can integrate this functionality with the &lt;strong&gt;DevExpress Blazor AI Chat&lt;/strong&gt; component (which relies on the &lt;code&gt;IChatClient&lt;/code&gt; interface).&lt;/p&gt;
&lt;p&gt;This class is designed to support LLM&amp;nbsp;switch while preserving individual conversation histories. Key considerations include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Chat Client Management:&lt;/strong&gt; Stores a list of &lt;code&gt;ChatClientSession&lt;/code&gt; objects, where each object represents an LLM and its associated chat history.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Message Handling:&lt;/strong&gt; Routes messages to the currently selected chat client and retrieves responses.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here’s the implementation:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;
using Microsoft.Extensions.AI;
//...
public class CompositeChatClient : IChatClient	{
    public List&amp;lt;ChatClientSession&amp;gt; AvailableChatClients { get; }
    public ChatClientSession? SelectedSession { get; set; }
    public CompositeChatClient(params ChatClientSession[] chatClients)	{
        AvailableChatClients = chatClients.ToList();
        SelectedSession = AvailableChatClients[0];
    }

    public Task&amp;lt;ChatResponse&amp;gt; GetResponseAsync(IEnumerable&amp;lt;ChatMessage&amp;gt; messages, ChatOptions? options = null,
        CancellationToken cancellationToken = new CancellationToken())	{
        return SelectedSession?.Client.GetResponseAsync(messages, options, cancellationToken);
    }

    public IAsyncEnumerable&amp;lt;ChatResponseUpdate&amp;gt; GetStreamingResponseAsync(IEnumerable&amp;lt;ChatMessage&amp;gt; messages, ChatOptions? options = null,
        CancellationToken cancellationToken = new CancellationToken())	{
        return SelectedSession?.Client.GetStreamingResponseAsync(messages, options, cancellationToken);
    }

    public void Dispose()	{
        for (int i = 0; i &amp;lt; AvailableChatClients.Count; i++)	{
            AvailableChatClients[i].Client.Dispose();
            AvailableChatClients[i].Messages.Clear();
        }
    }
    public object? GetService(Type serviceType, object? serviceKey = null) {
        throw new NotImplementedException();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, switch back to the &lt;code&gt;Program.cs&lt;/code&gt; and register &lt;code&gt;CompositeChatClient&lt;/code&gt; as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;
// Register both clients within a single instance of the IChatClient
var compositeChatClient = new CompositeChatClient(
    new ChatClientSession(azureChatClient, &amp;quot;Azure Open AI — GPT4o&amp;quot;), 
    new ChatClientSession(ollamaChatClient, &amp;quot;Ollama — Phi 4&amp;quot;));

builder.Services.AddScoped&amp;lt;IChatClient&amp;gt;((provider) =&amp;gt; compositeChatClient);
builder.Services.AddDevExpressAI();
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="llm-selection-implementation"&gt;LLM Selection Using a ComboBox&lt;/h2&gt;
&lt;p&gt;To allow LLM selection, open the razor page with the &lt;code&gt;DxAIChat&lt;/code&gt; component and add the &lt;a href="https://docs.devexpress.com/Blazor/DevExpress.Blazor.DxComboBox-2"&gt;DevExpress Blazor ComboBox&lt;/a&gt;. Key considerations include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CompositeChatClient Injection&lt;/strong&gt;: The &lt;code&gt;CompositeChatClient&lt;/code&gt; is injected to the page. It provides a list of available chat clients to the UI application. &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LLM Selection&lt;/strong&gt;: The &lt;code&gt;DxComboBox&lt;/code&gt; component is bound to a list of clients and triggers a callback when selection changes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chat Session Management&lt;/strong&gt;: The &lt;code&gt;OnModelChanged&lt;/code&gt; callback handles chat history save and load operations (when a user switches between LLMs).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here’s a snippet of the implementation:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;
@page &amp;quot;/&amp;quot;
@using DevExpress.AIIntegration.Blazor.Chat
@using DXBlazorChatSelector.Services
@using Microsoft.Extensions.AI

&amp;lt;div class=&amp;quot;main-container&amp;quot;&amp;gt;
    &amp;lt;div class=&amp;quot;top-container&amp;quot;&amp;gt;
        &amp;lt;DxComboBox Data=&amp;quot;@ModelsList&amp;quot;
        	CssClass=&amp;quot;selector-container-combo-editor&amp;quot;
        	TextFieldName=&amp;quot;@nameof(ChatClientSession.Name)&amp;quot;
            Value=&amp;quot;ChatClientProvider.SelectedSession&amp;quot;
        	ValueChanged=&amp;quot;@((ChatClientSession session) =&amp;gt; OnModelChanged(session))&amp;quot;/&amp;gt;
    	&amp;lt;/div&amp;gt;
    &amp;lt;DxAIChat @ref=&amp;quot;DxAiChat&amp;quot; CssClass=&amp;quot;my-chat&amp;quot;&amp;gt;&amp;lt;/DxAIChat&amp;gt;
&amp;lt;/div&amp;gt;

@code{

    [Inject]
    IChatClient? ChatClient { get; set; }
    CompositeChatClient ChatClientProvider =&amp;gt; ChatClient as CompositeChatClient;
    DxAIChat? DxAiChat { get; set; }
    List&amp;lt;ChatClientSession&amp;gt; ModelsList =&amp;gt; ChatClientProvider?.AvailableChatClients;

    private void OnModelChanged(ChatClientSession value)  {
        SaveLastAssistantMessage(DxAiChat.SaveMessages());
        ChatClientProvider.SelectedSession = value;
        DxAiChat.LoadMessages(ChatClientProvider.SelectedSession.Messages);
    }

    private void SaveLastAssistantMessage(IEnumerable&amp;lt;BlazorChatMessage&amp;gt; saveMessages)	{
        if(ChatClientProvider.SelectedSession != null) {
            ChatClientProvider.SelectedSession.Messages.Clear();
            ChatClientProvider.SelectedSession.Messages.AddRange(saveMessages);
        }
    }
}    
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id="start-a-new-chat"&gt;Start New Chat Implementation&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;To clear the message history for the selected LLM and start a new chat session&lt;/span&gt;, we will add a &lt;code&gt;DxButton&lt;/code&gt; and place it near the &lt;code&gt;DxComboBox&lt;/code&gt; in the &lt;code&gt;Index.razor&lt;/code&gt; page. Key considerations include:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;strong&gt;Button Style&lt;/strong&gt;: The button uses an SVG icon declared in CSS.&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;Session Reset&lt;/strong&gt;: On click, the button clears the message history for the selected LLM and updates the chat UI.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The updated code for the &lt;code&gt;Index.razor&lt;/code&gt; page:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;
@page &amp;quot;/&amp;quot;
@using DevExpress.AIIntegration.Blazor.Chat
@using DXBlazorChatSelector.Services
@using Microsoft.Extensions.AI

&amp;lt;div class=&amp;quot;main-container&amp;quot;&amp;gt;
    &amp;lt;div class=&amp;quot;top-container&amp;quot;&amp;gt;
    	&amp;lt;DxButton RenderStyle=&amp;quot;ButtonRenderStyle.Primary&amp;quot;
        			RenderStyleMode=&amp;quot;ButtonRenderStyleMode.Contained&amp;quot;
                  	IconCssClass=&amp;quot;refresh&amp;quot;
                  	IconPosition=&amp;quot;ButtonIconPosition.BeforeText&amp;quot;
                  	CssClass=&amp;quot;refresh-button&amp;quot;
                  	Text=&amp;quot;Start New Chat&amp;quot;
                  	Click=&amp;quot;ClearHistory&amp;quot;/&amp;gt;
        &amp;lt;DxComboBox Data=&amp;quot;@ModelsList&amp;quot;
        			CssClass=&amp;quot;selector-container-combo-editor&amp;quot;
        			TextFieldName=&amp;quot;@nameof(ChatClientSession.Name)&amp;quot;
            		Value=&amp;quot;ChatClientProvider.SelectedSession&amp;quot;
        			ValueChanged=&amp;quot;@((ChatClientSession session) =&amp;gt; OnModelChanged(session))&amp;quot;/&amp;gt;
    	&amp;lt;/div&amp;gt;
    &amp;lt;DxAIChat @ref=&amp;quot;DxAiChat&amp;quot; CssClass=&amp;quot;my-chat&amp;quot;&amp;gt;&amp;lt;/DxAIChat&amp;gt;
&amp;lt;/div&amp;gt;

@code{

    [Inject]
    IChatClient? ChatClient { get; set; }
    CompositeChatClient ChatClientProvider =&amp;gt; ChatClient as CompositeChatClient;
    DxAIChat? DxAiChat { get; set; }
    List&amp;lt;ChatClientSession&amp;gt; ModelsList =&amp;gt; ChatClientProvider?.AvailableChatClients;

 	private void ClearHistory()	{
        ChatClientProvider.SelectedSession.Messages.Clear();
        DxAiChat.LoadMessages(ChatClientProvider.SelectedSession.Messages);
    }
    private void OnModelChanged(ChatClientSession value)	{
        SaveLastAssistantMessage(DxAiChat.SaveMessages());
        ChatClientProvider.SelectedSession = value;
        DxAiChat.LoadMessages(ChatClientProvider.SelectedSession.Messages);
    }

    private void SaveLastAssistantMessage(IEnumerable&amp;lt;BlazorChatMessage&amp;gt; saveMessages)	{
        if(ChatClientProvider.SelectedSession != null) {
            ChatClientProvider.SelectedSession.Messages.Clear();
            ChatClientProvider.SelectedSession.Messages.AddRange(saveMessages);
        }
    }
}    
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;The Final Result&lt;/h2&gt;
&lt;p&gt;The following video demonstrates our implementation: &lt;/p&gt;
&lt;video controls=""&gt;
    &lt;source src="https://community.devexpress.com/blogs/aspnet/25.1/ai-multi-llm/blazor-ai-chat-multiple-llms.mp4" type="video/mp4"&gt;
    Your browser does not support the video tag.
&lt;/video&gt;
&lt;h2 id="review-our-github-example"&gt;Review our GitHub Example&lt;/h2&gt;
&lt;p&gt;To download a complete sample and explore the implementation, refer to the following GitHub Repository: &lt;a target="_blank" href="https://github.com/DevExpress-Examples/blazor-ai-chat-with-multiple-llm-services"&gt;DevExpress Blazor AI Chat — Implement Switching Between Multiple AI Services&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;By combining the power of the &lt;code&gt;IChatClient&lt;/code&gt; interface, the &lt;strong&gt;DevExpress Blazor ComboBox&lt;/strong&gt;, and the &lt;strong&gt;DevExpress Blazor AI Chat&lt;/strong&gt; component, you can deliver curated user experiences when using multiple LLMs.&lt;/p&gt;
&lt;p&gt;If you have any questions related to this implementation or would like to discuss AI-related integration needs, feel free to submit a support ticket via the &lt;a href="https://devexpress.com/ask"&gt;DevExpress Support Center&lt;/a&gt;. We&amp;#39;ll be happy to follow up.&lt;/p&gt;</description>
      <pubDate>Tue, 06 May 2025 23:40:00 Z</pubDate>
      <dc:creator>Dmitry Tokmachev (DevExpress)</dc:creator>
      <dx:excerpt>In this post, I’ll show you how to build a multi-LLM (Large Language Model) chat application that uses DevExpress Blazor AI Chat and ComboBox components.</dx:excerpt>
    </item>
    <item>
      <guid isPermaLink="false">bd716303-653c-428d-8b8a-a7d998cde032:388238</guid>
      <link>https://community.devexpress.com/Blogs/aspnet/archive/2025/04/23/blazor-early-access-preview-v25-1.aspx</link>
      <category domain="https://community.devexpress.com/Tags/2025">2025</category>
      <category domain="https://community.devexpress.com/Tags/Blazor">Blazor</category>
      <category domain="https://community.devexpress.com/Tags/EAP">EAP</category>
      <category domain="https://community.devexpress.com/Tags/v25.1">v25.1</category>
      <title>Blazor — Early Access Preview (v25.1)</title>
      <description>&lt;p&gt;
  &lt;span&gt;Our next major update (v25.1) is set for release in early June.&amp;nbsp;&lt;span&gt;In this post, I&amp;#39;ll summarize some of the features/capabilities available in our early access (EAP) build. Before I begin — a quick reminder: If you are an active&lt;/span&gt;&amp;nbsp;&lt;a href="https://www.devexpress.com/buy/net/"&gt;Universal or DXperience&lt;/a&gt;
&lt;span&gt;subscriber and want to explore upcoming v25.1-related features/capabilities before official release, you can download our EAP build via the&lt;/span&gt;&amp;nbsp;&lt;a href="https://www.devexpress.com/ClientCenter/DownloadManager/"&gt;DevExpress Download Manager&lt;/a&gt;&lt;span&gt;. Should you encounter issues with the EAP build, please submit a support ticket using the DevExpress Support Center.&lt;/span&gt;
  &lt;/span&gt;
&lt;/p&gt;
&lt;div class="Note"&gt;Early Access and CTP builds are provided solely for early testing purposes and are not ready for production use. This build can be installed side by side with other major versions of DevExpress products. Please backup your project and other important data before installing Early Access and CTP builds. This EAP does not include all features/products we expect to ship in our v25.1 release cycle. As its name implies, the EAP offers an early preview of what we expect to ship in two months.&lt;/div&gt;
&lt;h2 id="legacy-data-grid-combobox-tag-box-and-list-box-removal"&gt;Legacy Data Grid, ComboBox, Tag Box, and List Box are No Longer Available&lt;/h2&gt;

&lt;p&gt;
  &lt;span&gt;To streamline our distribution, we have removed the following legacy components from our v25.1 update:&lt;/span&gt;
&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;
    &lt;code&gt;DxDataGrid&lt;/code&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;code&gt;DxComboBoxLegacy&lt;/code&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;code&gt;DxTagBoxLegacy&lt;/code&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;code&gt;DxListBoxLegacy&lt;/code&gt;
  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To avoid issues, please check your projects for components from the&amp;nbsp; &lt;code&gt;DevExpress.Blazor.Legacy&lt;/code&gt;&amp;nbsp;namespace and migrate to new DevExpress alternatives. &lt;/p&gt;
&lt;p&gt;Helpful resources:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;
    &lt;a href="https://docs.devexpress.com/Blazor/403162/components/data-grid/migrate-from-data-grid-to-grid"&gt;Migrate from Data Grid to Grid&lt;/a&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;a href="https://supportcenter.devexpress.com/ticket/details/t1251358/data-grid-and-and-legacy-list-editors-were-moved-to-the-legacy-namespace"&gt;Legacy component deprecation details&lt;/a&gt;
  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you are still using older versions of DevExpress Blazor components, please contact us via the DevExpress&amp;nbsp;&lt;a href="https://supportcenter.devexpress.com/ticket/list" target="_blank"&gt;Support Center&lt;/a&gt; and let us know how we can help you migrate to newer&amp;nbsp;alternatives.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
  &lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
  &lt;span style="font-family:&amp;#39;Open Sans Condensed&amp;#39;, HelveticaNeue-CondensedBold, Helvetica, &amp;#39;Arial Narrow&amp;#39;, Calibri, Arial, &amp;#39;Lucida Grande&amp;#39;, sans-serif;font-size:30px;"&gt;Blazor Editors&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
  &lt;span style="font-family:&amp;#39;Open Sans Condensed&amp;#39;, HelveticaNeue-CondensedBold, Helvetica, &amp;#39;Arial Narrow&amp;#39;, Calibri, Arial, &amp;#39;Lucida Grande&amp;#39;, sans-serif;font-size:30px;"&gt;
    &lt;br&gt;
  &lt;/span&gt;
  &lt;span style="font-family:&amp;#39;Open Sans Condensed&amp;#39;, HelveticaNeue-CondensedBold, Helvetica, &amp;#39;Arial Narrow&amp;#39;, Calibri, Arial, &amp;#39;Lucida Grande&amp;#39;, sans-serif;color:#656565;font-size:24px;"&gt;Blazor ComboBox —&amp;nbsp;Set Data Load Mode&amp;nbsp;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
  &lt;span&gt;The DevExpress Blazor ComboBox allows you to manage data source interactions using &lt;code&gt;DataLoadMode&lt;/code&gt;. Since v24.1, our Blazor ComboBox caches data to reduce frequent database requests. You can now set &lt;code&gt;DataLoadMode&lt;/code&gt; to &lt;code&gt;OnDemand&lt;/code&gt; (similar to behaviors available prior to v24.1). This option allows the ComboBox to fetch data from the data source each time the dropdown activates. When this option is used, our Blazor&amp;nbsp;ComboBox does not preload data when the page loads (improving&amp;nbsp;initial page load speed.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;
  &lt;span&gt;
    &lt;br&gt;
  &lt;/span&gt;
  &lt;span style="color:#656565;font-family:&amp;#39;Open Sans Condensed&amp;#39;, HelveticaNeue-CondensedBold, Helvetica, &amp;#39;Arial Narrow&amp;#39;, Calibri, Arial, &amp;#39;Lucida Grande&amp;#39;, sans-serif;font-size:24px;"&gt;Blazor&amp;nbsp;List Box — Select All&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
  &lt;span&gt;The DevExpress Blazor List Box allows you to display a Select All check box above list box items.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;
  &lt;span&gt;
    &lt;span&gt;To explore the capabilities of the EAP version of the DevExpress Blazor List Box control, open our locally installed Blazor demo:&amp;nbsp;&lt;strong&gt;ListBox&lt;/strong&gt;
    &lt;/span&gt;
    &lt;strong&gt;&amp;nbsp;&lt;/strong&gt;
    &lt;strong&gt;→ Multiple Selection&lt;/strong&gt;
    &lt;span&gt;.&lt;/span&gt;
  &lt;/span&gt;
&lt;/p&gt;
&lt;h2 id="app-showcase-demo"&gt;App Showcase Demo&lt;/h2&gt;
&lt;p&gt;New CRM, Analytics, and Scheduling/Planning modules (built with our Blazor Grid, TreeList, Scheduler, ListBox, ComboBox, Charts, and other DevExpress Blazor components).&lt;/p&gt;
&lt;p&gt;Our showcase demo utilizes &lt;code&gt;InteractiveAuto&lt;/code&gt; render mode, introduced in .NET 8 —&amp;nbsp;starting with Blazor Server for fast initial load and seamlessly transitioning to WebAssembly (WASM) for optimal speed and responsiveness.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;The application&amp;nbsp;uses our new Fluent theme with light/dark mode support. Each module is built with reusable code, so you can easily adapt/integrate module components into your next DevExpress-powered Blazor project.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
  &lt;img src="https://community.devexpress.com/blogs/aspnet/v25.1/app-showcase.png" alt="app showcase"&gt;
&lt;/p&gt;
&lt;p&gt;
  &lt;span&gt;To explore the capabilities of the demo, open our locally installed showcase demo:&amp;nbsp;&lt;code&gt;DevExpress Demos 25.1\Components\Blazor\BlazorDemo.Showcase&lt;/code&gt;&amp;nbsp;or visit&lt;span&gt;
      &lt;a id="menur7m7o" href="https://demos.devexpress.com/blazor-showcase/" rel="noreferrer noopener" target="_blank" title="https://demos.devexpress.com/blazor-showcase"&gt;https://demos.devexpress.com/blazor-showcase/&lt;/a&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;
&lt;/p&gt;
&lt;h2 id="pivot-table-official-release"&gt;Blazor Pivot Table&lt;/h2&gt;
&lt;h3 id="filter-data"&gt;Filter Data&lt;/h3&gt;
&lt;p style="color:#161616;"&gt;The DevExpress Blazor&amp;nbsp;&lt;a href="https://docs.devexpress.com/Blazor/405245/pivot-table"&gt;Pivot Table&lt;/a&gt;&amp;nbsp;allows you to apply filters to fields displayed in the Filter Header Area. You can define these filter fields in component markup or drag them from other Pivot Table areas. Use the&amp;nbsp; &lt;span&gt;
    &lt;code&gt;FilterHeaderAreaDisplayMode&lt;/code&gt;
  &lt;/span&gt;&amp;nbsp;property to control Filter Header Area visibility. &lt;/p&gt;
&lt;p style="color:#161616;"&gt;Filter field headers display filter menu buttons. Users can press these buttons to open Field Filter Menus. You can use the following properties to control filter menu button visibility:&lt;/p&gt;
&lt;ul style="color:#161616;"&gt;
  &lt;li&gt;
    &lt;span&gt;
      &lt;code&gt;DxPivotTable.FilterMenuButtonDisplayMode&lt;/code&gt;
    &lt;/span&gt;&amp;nbsp;- Specifies whether a filter menu button is visible for all filter field headers.
  &lt;/li&gt;
  &lt;li&gt;
    &lt;span&gt;
      &lt;code&gt;DxPivotTableField.FilterMenuButtonDisplayMode&lt;/code&gt;
    &lt;/span&gt;&amp;nbsp;- Specifies whether a filter menu button is visible for a specific field.
  &lt;/li&gt;
&lt;/ul&gt;
&lt;p style="color:#161616;"&gt;The Field Filter Menu displays a drop-down window with all unique values of the field. Users can select/deselect these values to filter Pivot Table data. &lt;/p&gt;
&lt;p style="color:#161616;"&gt;You can use the following APIs to customize the filter menu as requirements dictate:&lt;/p&gt;
&lt;ul style="color:#161616;"&gt;
  &lt;li&gt;The&amp;nbsp; &lt;code&gt;CustomizeFilterMenu&lt;/code&gt;&amp;nbsp;event fires before the drop-down filter is displayed and allows you to customize filter items. &lt;/li&gt;
  &lt;li&gt;The&amp;nbsp; &lt;code&gt;FilterMenuTemplate&lt;/code&gt;&amp;nbsp;property specifies the template used for the content displayed within the field&amp;#39;s drop-down filter. &lt;/li&gt;
  &lt;li&gt;The&amp;nbsp; &lt;code&gt;FieldFilterMenuTemplate&lt;/code&gt;&amp;nbsp;property specifies the template used for all drop-down filter menus in the Pivot Table. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;img src="https://community.devexpress.com/blogs/aspnet/25.1/EAP/pivot-filter-ui.png" alt="pivot grid filter ui"&gt;
&lt;/p&gt;
&lt;p&gt;In addition to the UI-based filtering options, t&lt;span style="color:#161616;"&gt;he DevExpress Blazor&amp;nbsp;&lt;/span&gt;Pivot Table &lt;span style="color:#161616;"&gt;&amp;nbsp;allows you to filter data in code.&amp;nbsp; &lt;span&gt;To apply filter criteria, create a&amp;nbsp;&lt;/span&gt;
    &lt;a href="https://docs.devexpress.com/CoreLibraries/2129/devexpress-data-library/criteria-operators"&gt;criteria operator&lt;/a&gt;
    &lt;span&gt;&amp;nbsp;object that specifies a filter expression and send this object to the&amp;nbsp;&lt;/span&gt;
    &lt;code&gt;SetFilterCriteria&lt;/code&gt;
    &lt;span&gt;&amp;nbsp;method.&lt;/span&gt;
  &lt;/span&gt;
  &lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
  &lt;span&gt;To explore the capabilities of the EAP version of the DevExpress Blazor Pivot Table control, open our locally installed Blazor demo:&amp;nbsp;&lt;/span&gt;
  &lt;strong&gt;Pivot Table&amp;nbsp;&lt;/strong&gt;
  &lt;strong&gt;→ Filter Data.&lt;/strong&gt;
  &lt;br&gt;
&lt;/p&gt;
&lt;h2 id="grid-treelist"&gt;Blazor Grid &amp;amp; TreeList&lt;/h2&gt;
&lt;h3 id="pdf-export"&gt;PDF Export&lt;/h3&gt;
&lt;div&gt;Our Blazor Grid and TreeList now support PDF export APIs. This feature allows you to generate PDF documents while preserving key data presentation elements, including:&lt;/div&gt;
&lt;ul&gt;
  &lt;li&gt;Column order, captions, and alignment&lt;/li&gt;
  &lt;li&gt;Value format and alignment&lt;/li&gt;
  &lt;li&gt;Group rows, group summaries, and group totals&lt;/li&gt;
  &lt;li&gt;Total summaries&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;We do not expect to support full WYSIWYG export -&amp;nbsp;some UI elements (such as the group panel, search panel, toolbar, and pager, as well as custom CSS styles) will be excluded.&lt;/div&gt;
&lt;p&gt;
  &lt;img src="https://community.devexpress.com/blogs/aspnet/25.1/EAP/grid-pdf-export.png" alt="grid pdf export"&gt;
&lt;/p&gt;
&lt;div&gt;To explore the capabilities of the EAP version of the DevExpress Blazor Grid control, open our locally installed Blazor demo: &amp;nbsp;&lt;strong&gt;Grid &lt;/strong&gt;
  &lt;strong&gt;→ Export → Export Data&lt;/strong&gt;.
&lt;/div&gt;

&lt;h3 id="keyboard-support-enhancements"&gt;Keyboard Support Enhancements&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Filter Row:&lt;/strong&gt; Users can now enter a new filter value even if a cell editor is inactive (no need to press Enter first).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cell Editing:&lt;/strong&gt; If the EditOnKeyPress property is enabled, users can begin typing to open an editor for a focused cell.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id="blazor-context-menu"&gt;Blazor Context Menu&lt;/h2&gt;
&lt;h3 id="performance-enhancements"&gt;Performance Enhancements&lt;/h3&gt;
&lt;p&gt;We optimized our Blazor Context Menu&amp;#39;s rendering logic to reduce the number of messages sent between the server and client. Depending on connection quality and the number of items, DevExpress Context Menus now open 20-50% faster when used in Blazor Server applications.&lt;/p&gt;  
&lt;p&gt;
  &lt;img src="https://community.devexpress.com/blogs/aspnet/25.1/EAP/context-menu-performance-enhancements.png" alt="context menu performance"&gt;
&lt;/p&gt;

&lt;h2&gt;Blazor Rich Text Editor&lt;/h2&gt;
&lt;h3&gt;Zoom Operations&lt;/h3&gt;
&lt;p&gt;
  &lt;span style="color:#2b2b2b;"&gt;With v25.1, the DevExpress Blazor Rich Text Editor allows you to zoom in/out of documents with ease (via the UI and in code). Users can modify document&amp;nbsp;zoom level using a drop-down menu within the View&lt;/span&gt;&amp;nbsp;R&lt;span style="color:#2b2b2b;"&gt;ibbon tab. Available levels range from 50%&lt;/span&gt;
  &lt;span style="color:#2b2b2b;"&gt;&amp;nbsp;to 200%&lt;/span&gt;
  &lt;span style="color:#2b2b2b;"&gt;.&amp;nbsp;Disable the &lt;code&gt;AllowZoom&lt;/code&gt; property to hide the drop-down zoom level menu.&amp;nbsp; &lt;span&gt;Irrespective of the&amp;nbsp;&lt;/span&gt;
    &lt;code&gt;AllowZoom&lt;/code&gt;
    &lt;span&gt;&amp;nbsp;property value, you can use the &lt;span&gt;
        &lt;code&gt;ZoomLevel&lt;/code&gt;
        &lt;span&gt;&amp;nbsp;&lt;/span&gt;
      &lt;/span&gt;
    &lt;/span&gt;
    &lt;span&gt;property to zoom a document at runtime.&lt;/span&gt;
  &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
  &lt;img src="https://community.devexpress.com/blogs/aspnet/v25.1/rich-zoom.png" alt="rich text editor zoom"&gt;
&lt;/p&gt;
&lt;p&gt;
  &lt;span&gt;To explore the capabilities of the EAP version of the DevExpress Blazor RichEdit control, open the following locally installed Blazor demo: &lt;/span&gt;&lt;strong&gt;Rich Text Editor &lt;/strong&gt;
  &lt;strong&gt;→ Overview&lt;/strong&gt;
  &lt;span&gt;.&lt;/span&gt;
  &lt;br&gt;
&lt;/p&gt;
&lt;h2 id="rich-text-editor"&gt;&lt;/h2&gt;
&lt;h2 id="scheduler"&gt;Blazor Scheduler&lt;/h2&gt;
&lt;h3 id="toolbar-customization"&gt;Toolbar Customization&lt;/h3&gt;
&lt;div&gt;The DevExpress Blazor Scheduler allows you to define custom toolbar items and customize the following built-in items:&lt;/div&gt;
&lt;ul&gt;
  &lt;li&gt;Today button&lt;/li&gt;
  &lt;li&gt;Next and Previous buttons&lt;/li&gt;
  &lt;li&gt;Date navigator&lt;/li&gt;
  &lt;li&gt;Resource navigator&lt;/li&gt;
  &lt;li&gt;Scheduler View selector&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;Customization options include:&lt;/div&gt;
&lt;ul&gt;
  &lt;li&gt;Position and alignment of toolbar items.&lt;/li&gt;
  &lt;li&gt;Enabled, Visible, Tooltip, and Render Style properties.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;Use the &lt;span&gt;
    &lt;code&gt;ToolbarItems&lt;/code&gt;
    &lt;span&gt;&amp;nbsp;tag to modify a collection of visible toolbar items. Declare &lt;span&gt;
        &lt;code&gt;DxToolbarItem&lt;/code&gt;
      &lt;/span&gt; objects to add custom items to this collection.&amp;nbsp;Alternatively, disable the &lt;code&gt;ShowToolbarArea&lt;/code&gt; property to hide the toolbar entirely. &lt;/span&gt;
  &lt;/span&gt;
&lt;/div&gt;
&lt;pre&gt;      &lt;code class="language-html"&gt;&amp;lt;DxScheduler ...&amp;gt;
    &amp;lt;ToolbarItems&amp;gt;
        &amp;lt;DxSchedulerPreviousIntervalToolbarItem /&amp;gt;
        &amp;lt;DxSchedulerNextIntervalToolbarItem /&amp;gt;
        &amp;lt;DxSchedulerTodayToolbarItem /&amp;gt;
        &amp;lt;DxSchedulerDateNavigatorToolbarItem /&amp;gt;
        &amp;lt;DxToolbarItem GroupName=&amp;quot;ScaleDuration&amp;quot;
                       Text=&amp;quot;1 day&amp;quot;
                       Click=&amp;quot;@((i) =&amp;gt; CurrentDuration = TimeSpan.FromHours(24))&amp;quot;
                       Checked=&amp;quot;@(CurrentDuration == TimeSpan.FromHours(24))&amp;quot;
                       BeginGroup=&amp;quot;true&amp;quot;
                       Alignment=&amp;quot;ToolbarItemAlignment.Right&amp;quot;&amp;gt;&amp;lt;/DxToolbarItem&amp;gt;
        &amp;lt;DxToolbarItem GroupName=&amp;quot;ScaleDuration&amp;quot;
                       Text=&amp;quot;2 days&amp;quot;
                       Click=&amp;quot;@((i) =&amp;gt; CurrentDuration = TimeSpan.FromHours(48))&amp;quot;
                       Checked=&amp;quot;@(CurrentDuration == TimeSpan.FromHours(48))&amp;quot;&amp;gt;&amp;lt;/DxToolbarItem&amp;gt;
        &amp;lt;DxToolbarItem GroupName=&amp;quot;ScaleDuration&amp;quot;
                       Text=&amp;quot;3 days&amp;quot;
                       Click=&amp;quot;@((i) =&amp;gt; CurrentDuration = TimeSpan.FromHours(72))&amp;quot;
                       Checked=&amp;quot;@(CurrentDuration == TimeSpan.FromHours(72))&amp;quot;&amp;gt;&amp;lt;/DxToolbarItem&amp;gt;
    &amp;lt;/ToolbarItems&amp;gt;
&amp;lt;/DxScheduler&amp;gt;&lt;/code&gt;
&lt;/pre&gt;
&lt;img src="https://community.devexpress.com/blogs/aspnet/25.1/EAP/scheduler-toolbar.png" alt="custom toolbar items"&gt;
&lt;p&gt;To explore the capabilities of the EAP version of the DevExpress Blazor Scheduler control, open the following locally installed Blazor demo: &lt;strong&gt;Scheduler&amp;nbsp;&lt;/strong&gt;
  &lt;strong&gt;→ Customization&amp;nbsp; &lt;strong&gt;→ Custom Toolbar Items&lt;/strong&gt;
  &lt;/strong&gt;. &lt;br&gt;
&lt;/p&gt;
&lt;h3 id="resizing-and-dragging-for-appointment-form"&gt; Appointment Form Resize and Drag Operations&lt;/h3&gt;
&lt;p&gt;You can now drag and resize our&amp;nbsp;&lt;a href="https://docs.devexpress.com/Blazor/404564/components/scheduler/customization/appointment-forms-and-tooltips#default-appointment-form" target="_blank"&gt;Extended Appointment Form&lt;/a&gt;&amp;nbsp;(it is now easier to view the entirety of a&amp;nbsp;calendar without discarding changes).  &lt;/p&gt;
&lt;h3 id="popup-performance-enhancements"&gt;&lt;/h3&gt;
&lt;h3 id="Performance-Enhancements" style="font-weight:600;color:#333333;"&gt;Performance Enhancements&lt;/h3&gt;
&lt;p style="color:#333333;"&gt;We enhanced performance for the following operations/usage scenarios:&lt;/p&gt;
&lt;ul style="color:#333333;"&gt;
  &lt;li&gt;Time needed to open Date Navigator and Resource Navigator popups&lt;/li&gt;
  &lt;li&gt;Appointment dragging&lt;/li&gt;
  &lt;li&gt;Time needed to open an appointment’s tooltip and compact/extended form&lt;/li&gt;
  &lt;li&gt;Creating, updating, and deleting appointments&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="UIUX-Enhancements" style="font-weight:600;color:#333333;"&gt;UI/UX Enhancements&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;strong&gt;Icons used for the Today button and each view selector (Day, Work Week, Month, Timeline).&lt;/strong&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;strong&gt;A dropdown button for the view selector.&lt;/strong&gt; In previous versions, we used a button group to select view type. With our new dropdown button, the UI requires less space, improving the user experience and allowing you to add additional custom items to the toolbar.
  &lt;/li&gt;
  &lt;li&gt;
    &lt;strong&gt;A new render style mode for built-in toolbar items.&lt;/strong&gt; We changed the render style mode to Plain.&amp;nbsp;&lt;/li&gt;
  &lt;li&gt;
    &lt;strong&gt;New appointment label colors in the Fluent theme.&lt;/strong&gt;&amp;nbsp;We updated&amp;nbsp;default label colors, replacing bright colors with a pastel palette. This modification was designed to improve visual clarity and reduces eye strain.&amp;nbsp;&lt;/li&gt;
  &lt;li&gt;
    &lt;strong&gt;New status styles for the Fluent theme.&lt;/strong&gt; Appointment statuses now use styles similar to those of Microsoft Outlook. 
  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;img src="https://community.devexpress.com/blogs/aspnet/25.1/EAP/scheduler-before.png" data-label-after="Blazor Scheduler (v24.2)" data-label-before="Blazor Scheduler (v25.1)" data-comparer-position="50" data-comparer-theme="dark" data-before-src="https://community.devexpress.com/blogs/aspnet/25.1/EAP/scheduler-after.png" alt=""&gt;
&lt;/p&gt;
&lt;h2 id="scheduler"&gt;Blazor Charts&lt;/h2&gt;
&lt;h3 id="toolbar-customization"&gt;Zoom-related APIs&lt;/h3&gt;
&lt;div&gt;New APIs include:&lt;/div&gt;
&lt;ul&gt;
  &lt;li&gt;
    &lt;span style="color:#161616;"&gt;&lt;code&gt;ZoomChanged&lt;/code&gt;
    &lt;/span&gt;
    &lt;span style="color:#161616;"&gt; event - triggers whenever a zoom or pan operation is performed.&lt;/span&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;code&gt;ResetVisualRange&lt;/code&gt; method - restores the maximum possible visual range. &lt;/li&gt;
  &lt;li&gt;&lt;code&gt;SetArgumentAxisVisualRange&lt;/code&gt;&amp;nbsp;method - applies a specific visual range to the argument axis. &lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Series Label API Enhancements&amp;nbsp;&lt;/h3&gt;
&lt;p&gt;
  &lt;span style="color:#333333;"&gt;v25.1 includes an expanded the list of series label options. &lt;/span&gt;    &lt;code style="color:#333333;"&gt;DxChartSeriesLabel&lt;/code&gt;
  &lt;span style="color:#333333;"&gt;&amp;nbsp;supports the following pie series label-related properties:&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;
    &lt;code&gt;TextOverflow&lt;/code&gt;&amp;nbsp;and&amp;nbsp; &lt;code&gt;WordWrap&lt;/code&gt;&amp;nbsp;- specifies how the Pie Chart displays text for&amp;nbsp;overflowing labels.
  &lt;/li&gt;
  &lt;li&gt;
    &lt;code&gt;RadialOffset&lt;/code&gt; - shifts pie series labels radially away from or towards the center of a chart.
  &lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Legend Click Events&lt;/h3&gt;
&lt;p&gt;v25.1 ships with&amp;nbsp;&lt;code&gt;DxChart.LegendClick&lt;/code&gt;, &lt;code&gt;DxPolarChart.LegendClick&lt;/code&gt;, and &lt;code&gt;DxPieChart.LegendClick&lt;/code&gt; events. Handle these events to execute custom logic when users click legend items.&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:&amp;#39;Open Sans Condensed&amp;#39;, HelveticaNeue-CondensedBold, Helvetica, &amp;#39;Arial Narrow&amp;#39;, Calibri, Arial, &amp;#39;Lucida Grande&amp;#39;, sans-serif;font-size:30px;"&gt;Y&lt;/span&gt;&lt;span style="font-family:&amp;#39;Open Sans Condensed&amp;#39;, HelveticaNeue-CondensedBold, Helvetica, &amp;#39;Arial Narrow&amp;#39;, Calibri, Arial, &amp;#39;Lucida Grande&amp;#39;, sans-serif;font-size:30px;"&gt;our Feedback Counts&lt;/span&gt;&lt;/p&gt;&lt;p&gt;If you have a specific question about our Blazor EAP (v25.1), feel free to submit a support ticket via the DevExpress&amp;nbsp;&lt;a href="https://supportcenter.devexpress.com/ticket/list" target="_blank"&gt;Support Center&lt;/a&gt;. We will be happy to follow-up.&amp;nbsp;&lt;/p&gt;&lt;p&gt;For additional information on what you can expect from our mid-year release, please refer to our&amp;nbsp;&lt;a href="https://community.devexpress.com/blogs/aspnet/archive/2025/02/20/blazor-june-2025-roadmap-v25-1.aspx" target="_blank"&gt;June 2025 Roadmap&lt;/a&gt;.&lt;/p&gt;</description>
      <pubDate>Wed, 23 Apr 2025 11:55:00 Z</pubDate>
      <dc:creator>Slava Khudyakov (DevExpress)</dc:creator>
      <dx:excerpt> In this post, I will summarize some of the features/capabilities available in our early access (EAP) build</dx:excerpt>
    </item>
    <item>
      <guid isPermaLink="false">bd716303-653c-428d-8b8a-a7d998cde032:388228</guid>
      <link>https://community.devexpress.com/Blogs/aspnet/archive/2025/04/09/devexpress-blazor-ai-chat-implement-function-calling.aspx</link>
      <category domain="https://community.devexpress.com/Tags/AI">AI</category>
      <category domain="https://community.devexpress.com/Tags/Blazor">Blazor</category>
      <category domain="https://community.devexpress.com/Tags/Semantic+Kernel">Semantic Kernel</category>
      <category domain="https://community.devexpress.com/Tags/Tool+Calling">Tool Calling</category>
      <title>DevExpress Blazor AI Chat — Implement Function Calling</title>
      <description>&lt;p&gt;Modern AI-powered applications require seamless interaction with external systems or internal app components. Many AI service providers now support &lt;strong&gt;function calling&lt;/strong&gt; (also known as tool calling), which allows AI models to trigger functions at runtime. This capability is of particular value for agentic workflows/applications wherein&amp;nbsp;AI needs to execute actions such as fetching data, invoking APIs, or initiating tasks within an application (from&amp;nbsp;scheduling appointments and modifying database info to updating the app’s appearance). &lt;/p&gt;
&lt;p&gt;The overall flow in this instance looks like this: instead of replying to a user message, the model requests a function invocation with specified arguments. The chat client then invokes the function and supplies the result back to the LLM. At this point, the LLM constructs a response considering the value returned from the function. &lt;/p&gt;
&lt;p&gt;In this guide, we&amp;#39;ll explore how to enable function calling in the DevExpress Blazor &lt;code&gt;DxAiChat&lt;/code&gt; component using: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;IChatClient&lt;/code&gt; interface from the &lt;strong&gt;Microsoft.Extensions.AI&lt;/strong&gt; library. &lt;/li&gt;
&lt;li&gt;Plugins from Microsoft&amp;#39;s Semantic Kernel. &lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="getting-started"&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;To get started, you must first integrate&amp;nbsp;the &lt;code&gt;DxAiChat&lt;/code&gt; component into your application (see our official guide for additional information): &lt;a target="_blank" href="https://docs.devexpress.com/Blazor/DevExpress.AIIntegration.Blazor.Chat.DxAIChat#add-an-ai-chat-to-a-project"&gt;Add AI Chat to a Project&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;Next, register your AI service. In this example, we’ll use Azure OpenAI. Here’s a sample &lt;code&gt;Program.cs&lt;/code&gt; setup: &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;

using Azure.AI.OpenAI;
using Microsoft.Extensions.AI;
...
var builder = WebApplication.CreateBuilder(args);
...
// Replace with your endpoint, API key, and deployed AI model name
string azureOpenAIEndpoint = Environment.GetEnvironmentVariable(&amp;quot;AZURE_OPENAI_ENDPOINT&amp;quot;);
string azureOpenAIKey = Environment.GetEnvironmentVariable(&amp;quot;AZURE_OPENAI_API_KEY&amp;quot;);
string deploymentName = string.Empty;
...
var azureChatClient = new AzureOpenAIClient(
    new Uri(azureOpenAIEndpoint),
    new AzureKeyCredential(azureOpenAIKey));

IChatClient chatClient = azureChatClient.AsChatClient(deploymentName);

builder.Services.AddDevExpressBlazor();
builder.Services.AddChatClient(chatClient);
builder.Services.AddDevExpressAI();
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Run the project to confirm that you can send messages and receive AI responses. &lt;/p&gt;
&lt;h2 id="tool-calling-with-ichatclient"&gt;Tool Calling with IChatClient&lt;/h2&gt;
&lt;p&gt;First, define a simple function to retrieve weather information for a specified city. In this example, this is &lt;code&gt;GetWeatherTool&lt;/code&gt;. To help AI understand how to invoke the &lt;code&gt;GetWeatherTool&lt;/code&gt; function, use the &lt;code&gt;System.ComponentModel.Description&lt;/code&gt; attribute for both the method and its parameters. LLM uses parameters to figure out the most suitable method call and plan a call sequence:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;using System.ComponentModel;
using Microsoft.Extensions.AI;

public class CustomAIFunctions
{
    public static AIFunction GetWeatherTool =&amp;gt; AIFunctionFactory.Create(GetWeather); 
    [Description(&amp;quot;Gets the current weather in the city&amp;quot;)]
    public static string GetWeather([Description(&amp;quot;The name of the city&amp;quot;)] string city)
    {
        switch (city)
        {
            case &amp;quot;Los Angeles&amp;quot;:
            case &amp;quot;LA&amp;quot;:
                return GetTemperatureValue(20);
            case &amp;quot;London&amp;quot;:
                return GetTemperatureValue(15);
            default:
                return $&amp;quot;The information about the weather in {city} is not available.&amp;quot;;
        }
    }
    static string GetTemperatureValue(int value)
    {
        var valueInFahrenheits = value * 9 / 5 + 32;
        return $&amp;quot;{valueInFahrenheits}\u00b0F ({value}\u00b0C)&amp;quot;;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Modify the chat client registration as shown below to provide a list of available functions and allow the client to invoke functions when responding to user questions. Ensure that you configure the chat client options first, as the method call sequence is crucial here:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;using Azure;
using Azure.AI.OpenAI;
using Microsoft.Extensions.AI;
...
IChatClient chatClient = new ChatClientBuilder(azureChatClient)
    .ConfigureOptions(opt =&amp;gt;
    {
        opt.Tools = [CustomAIFunctions.GetWeatherTool];
    })
    .UseFunctionInvocation()
    .Build();

builder.Services.AddChatClient(chatClient);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At this point, when the user asks the AI service about the weather, the service will automatically trigger the &lt;code&gt;GetWeatherTool&lt;/code&gt; function and add results into its response.&lt;/p&gt;
&lt;img class="small" src="https://community.devexpress.com/blogs/aspnet/25.1/ai-tool-calling/ext/blazor-ai-chat-tool-calling-meai1.png" alt="" style="width:600px;height:630px;"&gt;
&lt;h2&gt;Integrating Semantic Kernel Plugins&lt;/h2&gt;
&lt;p&gt;Microsoft Semantic Kernel  allows developers to incorporate advanced AI capabilities into their apps (including reasoning, workflow orchestration, and dynamic prompt engineering). Microsoft&amp;#39;s framework enhances AI-powered solutions by allowing apps to interact with plugins and manage memory more effectively. &lt;/p&gt;
&lt;p&gt;To begin, add the following NuGet packages to your project: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a target="_blank" href="https://www.nuget.org/packages/Microsoft.SemanticKernel"&gt;Microsoft.SemanticKernel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a target="_blank" href="https://www.nuget.org/packages/Microsoft.SemanticKernel.Plugins.Core/1.38.0-alpha"&gt;Microsoft.SemanticKernel.Plugins.Core&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a target="_blank" href="https://www.nuget.org/packages/Microsoft.SemanticKernel.Connectors.OpenAI"&gt;Microsoft.SemanticKernel.Connectors.OpenAI&lt;/a&gt; (or an appropriate connector for your AI provider)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you are already using the Semantic Kernel in your app and are familiar with the &lt;a target="_blank" href="https://learn.microsoft.com/en-us/semantic-kernel/concepts/plugins/?pivots=programming-language-csharp"&gt;Plugin&amp;nbsp;concept&lt;/a&gt;, you can easily connect it to our Blazor &lt;code&gt;DxAiChat&lt;/code&gt; control. &lt;/p&gt;
&lt;p&gt;Since DevExpress AI-powered APIs operate with LLMs using the &lt;code&gt;IChatClient&lt;/code&gt; interface, you need to implement the interface manually and invoke &lt;code&gt;IChatCompletionService&lt;/code&gt; methods from the Semantic Kernel: &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;using Microsoft.Extensions.AI;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.OpenAI;
...
public class SemanticKernelPluginCallingChatClient : IChatClient {
	private IChatCompletionService _chatCompletionService;
    private Kernel _kernel;
    private OpenAIPromptExecutionSettings _executionSettings;
    public SemanticKernelPluginCallingChatClient(Kernel kernel)
    {
    	_kernel = kernel;
        _chatCompletionService = _kernel.GetRequiredService();
        _executionSettings = new OpenAIPromptExecutionSettings() { ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions };
    }

	public async Task GetResponseAsync(IEnumerable chatMessages, ChatOptions? options = null, CancellationToken cancellationToken = default)
    {
        var history = GetChatHistory(chatMessages);
        ChatMessageContent message = await _chatCompletionService.GetChatMessageContentAsync(history, _executionSettings, _kernel, cancellationToken);
        return new ChatResponse(new ChatMessage(ChatRole.Assistant, message.Content));
    }

	public async IAsyncEnumerable GetStreamingResponseAsync(IEnumerable chatMessages, ChatOptions? options = null, CancellationToken cancellationToken = default)
	{
        var history = GetChatHistory(chatMessages);
        await foreach(var item in _chatCompletionService.GetStreamingChatMessageContentsAsync(history, _executionSettings, _kernel, cancellationToken)) {
        	yield return new ChatResponseUpdate(ChatRole.Assistant, item.Content);
    	}
    }
    
    AuthorRole GetRole(ChatRole chatRole) {
        if(chatRole == ChatRole.User) return AuthorRole.User;
        if(chatRole == ChatRole.System) return AuthorRole.System;
        if(chatRole == ChatRole.Assistant) return AuthorRole.Assistant;
        if(chatRole == ChatRole.Tool) return AuthorRole.Tool;
        throw new Exception();
    }

	private ChatHistory GetChatHistory(IEnumerable chatMessages)
    {
    	var history = new ChatHistory(chatMessages.Select(x =&amp;gt; new ChatMessageContent(GetRole(x.Role), x.Text)));
        return history;
    }
...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Implement a Semantic Kernel plugin similar to the previous function, but decorate the main function method with the &lt;code&gt;Microsoft.SemanticKernel.KernelFunction&lt;/code&gt; attribute: &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;using Microsoft.SemanticKernel;
using System.ComponentModel;
...

public class WeatherPlugin {
        [KernelFunction]
        [Description(&amp;quot;Gets the current weather in the city&amp;quot;)]
        public static string GetWeather([Description(&amp;quot;The name of the city&amp;quot;)] string city) {
            switch(city) {
                case &amp;quot;Los Angeles&amp;quot;:
                case &amp;quot;LA&amp;quot;:
                    return GetTemperatureValue(20);
                case &amp;quot;London&amp;quot;:
                    return GetTemperatureValue(15);
                default:
                    return $&amp;quot;The information about the weather in {city} is not available.&amp;quot;;
            }
        }
        static string GetTemperatureValue(int value)
        {
            var valueInFahrenheits = value * 9 / 5 + 32;
            return $&amp;quot;{valueInFahrenheits}\u00b0F ({value}\u00b0C)&amp;quot;;
        }
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, register the Semantic Kernel and the chat client during app startup: &lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Plugins.Core;
...
    
var semanticKernelBuilder = Kernel.CreateBuilder();
semanticKernelBuilder.AddAzureOpenAIChatCompletion(
    deploymentName,
    azureOpenAIEndpoint,
    azureOpenAIKey);

// Add plugins from Microsoft.SemanticKernel.Plugins.Core
#pragma warning disable SKEXP0050
semanticKernelBuilder.Plugins.AddFromType&amp;lt;TimePlugin&amp;gt;(); // this is a built-in plugin
semanticKernelBuilder.Plugins.AddFromType&amp;lt;WeatherPlugin&amp;gt;(); // this is our custom plugin
#pragma warning restore SKEXP0050

var globalKernel = semanticKernelBuilder.Build();
builder.Services.AddChatClient(new SemanticKernelPluginCallingChatClient(globalKernel));

builder.Services.AddDevExpressAI();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once configured, your application will use the Semantic Kernel plugin to intelligently&amp;nbsp;handle requests:&lt;/p&gt;
&lt;img class="small" src="https://community.devexpress.com/blogs/aspnet/25.1/ai-tool-calling/ext/blazor-ai-chat-tool-calling-semantic-kernel1.png" alt="" style="width:600px;height:630px;"&gt;

&lt;h2 id="additional-resources"&gt;Additional Resources&lt;/h2&gt;
&lt;p&gt;For an in-depth understanding of Semantic Kernel tool calling, please review the following YouTube video: &lt;a target="_blank" href="https://youtu.be/0eM3CfHFM1c?si=Sr-imaYBBATTKuD9"&gt;Core GenAI Techniques - Function Calling&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;You can also explore the following DevExpress GitHub sample: &lt;a target="_blank" href="https://github.com/DevExpress-Examples/blazor-ai-chat-function-calling" title="DevExpress Blazor AI Chat — Implement Function/Tool Calling"&gt;DevExpress Blazor AI Chat — Implement Function/Tool Calling&lt;/a&gt;.&lt;/p&gt;</description>
      <pubDate>Wed, 09 Apr 2025 00:15:00 Z</pubDate>
      <dc:creator>Dmitry Tokmachev (DevExpress)</dc:creator>
    </item>
    <item>
      <guid isPermaLink="false">bd716303-653c-428d-8b8a-a7d998cde032:388227</guid>
      <link>https://community.devexpress.com/Blogs/aspnet/archive/2025/03/24/devexpress-blazor-ai-chat-ai-assistants-for-report-viewer-and-grid.aspx</link>
      <category domain="https://community.devexpress.com/Tags/AI">AI</category>
      <category domain="https://community.devexpress.com/Tags/Assistant">Assistant</category>
      <category domain="https://community.devexpress.com/Tags/Blazor">Blazor</category>
      <category domain="https://community.devexpress.com/Tags/Grid">Grid</category>
      <category domain="https://community.devexpress.com/Tags/Reporting">Reporting</category>
      <title>DevExpress Blazor AI Chat — AI Assistants for Report Viewer and Grid</title>
      <description>&lt;p&gt;In this post, I will detail how you can&amp;nbsp;integrate our Blazor &lt;code&gt;DxAIChat&lt;/code&gt; component in your project and provide Copilot-like AI assistants to your end-users.&lt;/p&gt;
&lt;p&gt;First, a quick word about this implementation...by incorporating the DevExpress AI-powered Chat component and associated natural language processing services, your DevExpress-powered Blazor app can efficiently filter/analyze/summarize data, generate document insights, ask contextual questions, and obtain answers related to reports, tables, and more. &lt;/p&gt;
&lt;img src="https://community.devexpress.com:443/blogs/aspnet/25.1/grid-report-assistants/blazor-grid-ai-assistant.png" alt="DevExpress Blazor Grid – AI Assistant" style="width:1578px;height:792px;"&gt;
&lt;h2 id="explore-the-github-example"&gt;Review our&amp;nbsp;GitHub Example&lt;/h2&gt;
&lt;p&gt;To help illustrate what&amp;#39;s possible, we published a working example on GitHub. This example&amp;nbsp;features the DevExpress Blazor Report Viewer and Grid control and includes a detailed README with implementation guidelines and practical usage scenarios:&lt;/p&gt;
&lt;p&gt;&lt;a target="_blank" href="https://github.com/DevExpress-Examples/blazor-grid-and-report-viewer-integrate-ai-assistant/tree/24.2.6%2B"&gt;Blazor Grid and Report Viewer — Incorporate an AI Assistant (Azure OpenAI) in your next DevExpress-powered Blazor app&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="expanding-ai-integration-to-winforms-and-wpf"&gt;Expanding AI Integration to WinForms and WPF&lt;/h2&gt;
&lt;p&gt;A similar AI assistant implementation can also be applied to WinForms and WPF-powered applications (apps&amp;nbsp;that support data export to Excel and/or PDF). If you are looking to introduce a Copilot-like assistant into your next great WinForms/WPF app, please refer to our Blazor &lt;code&gt;DxAIChat&lt;/code&gt; component implementation guide in the following example: &lt;/p&gt;
&lt;p&gt;&lt;a target="_blank" href="https://github.com/DevExpress-Examples/devexpress-ai-chat-samples"&gt;Blazor AI Chat - How to add the DevExpress Blazor AI Chat component to your next Blazor, MAUI, WPF, and WinForms application&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.devexpress.com/subscriptions/i/24.2/24-2-blazor-new-ai-chat-multiple-platforms.png" alt="DevExpress AI Chat Controls"&gt;&lt;/p&gt;
&lt;h2&gt;Share Your Feedback&lt;/h2&gt;
&lt;p&gt;We appreciate your continued support and enthusiasm for DevExpress tools. If you have any questions or would like to discuss AI-related integration needs, please submit a support ticket via the &lt;a target="_blank" href="https://devexpress.com/ask"&gt;DevExpress Support Center&lt;/a&gt;.&amp;nbsp;&lt;/p&gt;</description>
      <pubDate>Mon, 24 Mar 2025 03:35:00 Z</pubDate>
      <dc:creator>Dmitry Tokmachev (DevExpress)</dc:creator>
    </item>
    <item>
      <guid isPermaLink="false">bd716303-653c-428d-8b8a-a7d998cde032:388222</guid>
      <link>https://community.devexpress.com/Blogs/aspnet/archive/2025/02/20/blazor-june-2025-roadmap-v25-1.aspx</link>
      <category domain="https://community.devexpress.com/Tags/2025">2025</category>
      <category domain="https://community.devexpress.com/Tags/Blazor">Blazor</category>
      <category domain="https://community.devexpress.com/Tags/Featured">Featured</category>
      <category domain="https://community.devexpress.com/Tags/Roadmap">Roadmap</category>
      <category domain="https://community.devexpress.com/Tags/Survey">Survey</category>
      <category domain="https://community.devexpress.com/Tags/v25.1">v25.1</category>
      <title>Blazor — June 2025 Roadmap (v25.1)</title>
      <description>&lt;p&gt;This post outlines key features/enhancements planned for our next major update (v25.1) in June 2025.&lt;/p&gt;
&lt;p&gt;As always, if you have questions or suggestions, feel free to share your thoughts in the survey at the end of this post or submit a ticket via the &lt;a href="https://supportcenter.devexpress.com/ticket/list"&gt;DevExpress Support Center&lt;/a&gt;.&lt;/p&gt;
&lt;div class="Note"&gt;
    &lt;p&gt;The information contained within this blog post details our current/projected development plans. Please note that this information is being shared for INFORMATIONAL PURPOSES ONLY and does not represent a binding commitment on the part of Developer Express Inc. This roadmap and the features/products listed within it are subject to change. You should not rely on or use this information to help make a purchase decision about Developer Express Inc products.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id="live-roadmap-updates"&gt;Live Roadmap Updates&lt;/h2&gt;
&lt;p&gt;This roadmap will be regularly updated to reflect development progress. As we get closer to the release, we expect to add more items and modify the status of planned features. Look for the following labels next to every feature:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;p class="tags"&gt;&lt;span class="not-started"&gt;Planned&lt;/span&gt; — Feature is scheduled but not yet in development.&lt;/p&gt;&lt;/li&gt;
    &lt;li&gt;&lt;p class="tags"&gt;&lt;span class="development"&gt;In Development&lt;/span&gt; — Under active development.&lt;/p&gt;&lt;/li&gt;
    &lt;li&gt;&lt;p class="tags"&gt;&lt;span class="completed"&gt;Coming in EAP v25.1&lt;/span&gt; — Will be available in our first v25.1 early access preview.&lt;/p&gt;&lt;/li&gt;
    &lt;li&gt;&lt;p class="tags"&gt;&lt;span class="completed"&gt;Coming in v25.1&lt;/span&gt; — Will be included in the final v25.1 release.&lt;/p&gt;&lt;/li&gt;
    &lt;li&gt;&lt;p class="tags"&gt;&lt;span class="completed"&gt;Released in v25.1&lt;/span&gt; — Fully implemented and available.&lt;/p&gt;&lt;/li&gt;
    
&lt;/ul&gt;
&lt;h2 id="legacy-data-grid-combobox-tag-box-and-list-box-removal"&gt;Legacy Data Grid, ComboBox, Tag Box, and List Box Removal&lt;/h2&gt;
&lt;p&gt;Over the past three years, we have transitioned our Blazor components from a custom-built Blazor-specific data engine to the cross-platform &lt;code&gt;DevExpress.Data&lt;/code&gt; library. The ComboBox, Tag Box, and List Box components only saw internal changes and maintained the same API, while our Data Grid (&lt;code&gt;DxDataGrid&lt;/code&gt;) has been replaced with the new DevExpress Blazor Grid (&lt;code&gt;DxGrid&lt;/code&gt;). New components are more robust, utilize modern development practices, and benefit from the same powerful data engine used by our Data Grids for WinForms, Web Forms, and WPF.&lt;/p&gt;
&lt;p&gt;To streamline our libraries and accelerate future development, we will remove the following legacy components in our v25.1 update:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;code&gt;DxDataGrid&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;&lt;code&gt;DxComboBoxLegacy&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;&lt;code&gt;DxTagBoxLegacy&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;&lt;code&gt;DxListBoxLegacy&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To avoid disruptions, please check your projects for components from the &lt;code&gt;DevExpress.Blazor.Legacy&lt;/code&gt; namespace and migrate to new DevExpress alternatives.&lt;/p&gt;
&lt;p&gt;Helpful resources:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://docs.devexpress.com/Blazor/403162/components/data-grid/migrate-from-data-grid-to-grid"&gt;Migrate from Data Grid to Grid&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://supportcenter.devexpress.com/ticket/details/t1251358/data-grid-and-and-legacy-list-editors-were-moved-to-the-legacy-namespace"&gt;Legacy component deprecation details&lt;/a&gt;&lt;/p&gt;
&lt;div data-survey-id="34a70562-ec1e-437f-817d-81afc17cf873" data-survey-auth-required="false"&gt;&lt;/div&gt;
&lt;h2 id="focus-on-performance-and-stability"&gt;Focus on Performance and Stability&lt;/h2&gt;
&lt;p&gt;While expanding our Blazor component suite remains a top priority, we are also investing heavily in polishing and performance optimizations this year. We will share additional info as we approach our mid-year release — but our ultimate goal is to ensure smooth, responsive user experiences across all DevExpress Blazor components.&lt;/p&gt;
&lt;h2&gt;.NET Upgrade Assistant Integration for Project Upgrades&lt;/h2&gt;
&lt;p&gt;We expect to ship a new plugin (VSIX) for Microsoft&amp;#39;s .NET Upgrade Assistant. We expect this plugin to ultimately replace the DevExpress Project Converter for .NET 8+ projects.&amp;nbsp;Benefits&amp;nbsp;will include the following:&lt;/p&gt;
&lt;ul&gt;
   &lt;li&gt;Unlike our Project Converter, the new plugin will have access to NuGet, Roslyn, MEF, and other IDE services. With the .NET Upgrade Assistant&amp;#39;s auto–fix capabilities, we can automatically detect and safely resolve breaking changes in DevExpress code. This includes but is not limited to obsolete code replacements (such as, Font &amp;gt; DXFont, DxPivotGrid &amp;gt; DxPivotTable, etc.).&lt;/li&gt;
   &lt;li&gt;We will deliver the new plugin for minor and major DevExpress versions. The plugin will include the most recent&amp;nbsp;Directory.Packages.props file updates (with DevExpress–compatible 3rd party dependencies for CPM). You will be able to update all project dependencies and resolve security vulnerabilities with a single click.​&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Our Unified Component Installer will automatically install the new plug–in. The plugin will also be able for download from the Visual Studio Marketplace, nuget.org, and nuget.devexpress.com.&lt;br&gt;&lt;/p&gt;
&lt;h2 id="fluent-theme-official-release"&gt;Fluent Theme — Official Release&lt;/h2&gt;
&lt;p&gt;The DevExpress Blazor Fluent theme, introduced as a CTP in v24.2, will be production-ready in v25.1. Apart from polishing and visual enhancements/fixes for all components, we expect to introduce the following new features.&lt;/p&gt;
&lt;h3 id="built-in-and-custom-accent-colors"&gt;Built-in and Custom Accent Colors&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Coming in v25.1&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Our Fluent theme will ship with a set of built-in accent color options.&lt;/p&gt;
&lt;img src="https://community.devexpress.com/blogs/aspnet/v25.1/Fluent%20-%20Built-in%20Color%20Presets@2x.png" alt="color presets"&gt;
&lt;p&gt;Developers will also be able to configure custom accent colors to match user preferences or brand colors.&lt;/p&gt;
&lt;h3 id="different-icons-for-every-size-mode"&gt;Different Icons for Every Size Mode&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Coming in v25.1&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Instead of scaling icons, our Blazor components will use unique icon sets for every size mode - Small, Medium, and Large. This will ensure consistent and pixel-perfect appearance for your apps regardless of the selected sizing option.&lt;/p&gt;
&lt;img src="https://community.devexpress.com/blogs/aspnet/v25.1/Fluent%20-%20Different%20icons%20for%20size%20modes.png" alt="icon sizes"&gt;
&lt;h3 id="updated-fluent-ui-kit"&gt;Updated Fluent UI Kit&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Coming in v25.1&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We&amp;#39;ve recently updated our Fluent UI Kit on Figma. In v25.1, it will be expanded to include all key DevExpress Blazor components.&lt;/p&gt;
&lt;div data-survey-id="ede119c3-3f93-41a4-8173-fcc6f0025c42" data-survey-auth-required="false"&gt;&lt;/div&gt;
&lt;h2 id="blazor-package-size-optimization"&gt;Blazor Package Size Optimization&lt;/h2&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Coming in v25.1&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We plan to optimize the size of our Blazor libraries to increase initial loading speed and reduce the download size of your Blazor apps. Apart from removing legacy components, we plan to extract our themes/CSS into two separate packages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fluent themes&lt;/li&gt;
&lt;li&gt;Extra themes (Blazing Berry, Blazing Dark, Office White, Purple)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We will also consider fully or partially removing default Bootstrap CSS that ships with our Blazor themes, as it can be downloaded separately.&lt;/p&gt;
&lt;div data-survey-id="197be7ed-08ec-4154-827a-13083378a52b" data-survey-auth-required="false"&gt;&lt;/div&gt;
&lt;h2 id="app-showcase-demo"&gt;App Showcase Demo&amp;nbsp;&lt;strong style="font-family:&amp;#39;Segoe UI&amp;#39;, &amp;#39;Helvetica Neue&amp;#39;, Helvetica, Arial, sans-serif;font-size:14px;"&gt;&lt;a href="https://supportcenter.devexpress.com/ticket/details/t1278687/app-showcase-demo-blazor-roadmap-for-v25-1" target="_blank"&gt;(Discussion)&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Coming in EAP v25.1&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Our upcoming App Showcase will demonstrate common UI/UX patterns seen in modern business applications, built entirely with DevExpress Blazor components. Each demo module will prioritize clean, reusable code, making it easy to adapt.&amp;nbsp;&lt;/p&gt;
&lt;img src="https://community.devexpress.com/blogs/aspnet/v25.1/app-showcase.png" alt="app showcase"&gt;
&lt;h2 id="new-project-template-gallery"&gt;New Project Template Gallery&lt;/h2&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Coming in v25.1&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We will expand the DevExpress Blazor Templates collection available in the &lt;a href="https://docs.devexpress.com/Blazor/405308/get-started/template-kit"&gt;DevExpress Cross-IDE Project Template Kit&lt;/a&gt;. The new Template Kit will also be installed  alongside Blazor components and will become the default starting point for new DevExpress-based Blazor apps.&lt;/p&gt;
&lt;img src="https://community.devexpress.com/blogs/aspnet/v25.1/devexpress-template-kit-blazor.png" alt="app showcase"&gt;
&lt;h2 id="pivot-table-official-release"&gt;Blazor Pivot Table — Official Release&amp;nbsp;&lt;strong style="font-family:&amp;#39;Segoe UI&amp;#39;, &amp;#39;Helvetica Neue&amp;#39;, Helvetica, Arial, sans-serif;font-size:14px;"&gt;&lt;a href="https://supportcenter.devexpress.com/ticket/details/t1278693/feature-discussion-blazor-pivot-table-official-release" target="_blank"&gt;(Discussion)&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p class="tags"&gt;&lt;span class="not-started"&gt;Postponed until v25.2&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;In v25.1, we plan to officially release our Pivot Table component. The production-ready version will be more robust and will include new features that will allow end-users to manipulate data directly in the UI.&lt;/p&gt;
&lt;h3 id="field-reordering"&gt;Field Reordering&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Coming in v25.1&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Field reordering will allow you to drag a field to any location within the same area or between available areas (Columns, Rows, or Data). This will allow end-users to modify the way they analyze data on the fly. New APIs will allow you to configure which Pivot Tables fields can be dragged.&lt;/p&gt;
&lt;img src="https://community.devexpress.com/blogs/aspnet/v25.1/Field%20Reorder.png" alt="field reordering"&gt;
&lt;h3 id="filter-data"&gt;Filter Data&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Coming in EAP v25.1&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We plan to introduce a built-in filtering UI to the Blazor Pivot Table. End-users will be able to filter column and row values using filter menu buttons in field headers. The filter menu will be similar to that of our Blazor&amp;nbsp;&lt;a href="https://demos.devexpress.com/blazor/Grid/Filtering/ColumnFilterMenu"&gt;Grid&lt;/a&gt;. Clicking the filter menu button will display a list of field values, allowing you to select which&amp;nbsp;to display. For DateTime fields, the filter menu will display a hierarchical list.&lt;/p&gt;
&lt;img src="https://community.devexpress.com/blogs/aspnet/v25.1/PivotGrid%20-%20Filter%20DropDown.png" alt="pivot table filter menu"&gt;
&lt;p&gt;Developers will also be able to filter data in code using new API members: &lt;code&gt;SetFilterCriteria&lt;/code&gt;, &lt;code&gt;GetFilterCriteria&lt;/code&gt;, and &lt;code&gt;FilterCriteriaChanged&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="ribbon-official-release"&gt;Blazor Ribbon — Official Release&lt;/h2&gt;
&lt;p class="tags"&gt;&lt;span class="not-started"&gt;Postponed until v25.2&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Our Blazor Ribbon, introduced as a CTP in v24.2, will be officially released. We will polish its look and feel and refine adaptivity and overflow menu behavior to ensure seamless interactions for applications that require a large set of commands.&lt;/p&gt;
&lt;p&gt;The production-ready version will allow developers to replicate the single-line version of Ribbon interfaces used in modern MS Office apps (also known as Simplified Ribbon).&lt;/p&gt;
&lt;h2 id="ai-chat"&gt;Blazor AI Chat&lt;/h2&gt;
&lt;h3 id="prompt-suggestions"&gt;Prompt Suggestions&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Coming in v25.1&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;With v25.1,&amp;nbsp;you will be able to display prompt suggestions via bubbles next to the input field when using the DevExpress Blazor AI Chat control (to guide chat users to possible actions).&lt;/p&gt;
&lt;img src="https://community.devexpress.com/blogs/aspnet/v25.1/AI%20Chat%20-%20Prompt%20Suggestions.png" alt="ai chat prompt suggestions"&gt;
&lt;h3 id="file-attachments"&gt;File Attachments&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Coming in v25.1&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;You will also be able to attach files when sending messages.&lt;/p&gt;
&lt;img src="https://community.devexpress.com/blogs/aspnet/v25.1/AI%20Chat%20-%20File%20Attachments%20x2.png" alt="ai chat attach file"&gt;
&lt;h3 id="api-to-reuse-an-existing-openai-assistant"&gt;API to Reuse an Existing OpenAI Assistant&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Coming in v25.1&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Our Blazor AI Chat control will be able to connect to an already initialized &lt;a href="https://learn.microsoft.com/en-us/dotnet/api/overview/azure/ai.openai.assistants-readme"&gt;OpenAI Assistant&lt;/a&gt;. This will allow you to&amp;nbsp;use a single OpenAI Assistant instance to initiate multiple tasks within&amp;nbsp;a single app.&lt;/p&gt;
&lt;h2 id="grid-treelist"&gt;Blazor Grid &amp;amp; TreeList&amp;nbsp;&lt;strong style="font-family:&amp;#39;Segoe UI&amp;#39;, &amp;#39;Helvetica Neue&amp;#39;, Helvetica, Arial, sans-serif;font-size:14px;"&gt;&lt;a href="https://supportcenter.devexpress.com/ticket/details/t1278695/feature-discussion-grid-treelist-blazor-roadmap-for-v25-1" target="_blank"&gt;(Discussion)&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;h3 id="pdf-export"&gt;PDF Export&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Coming in EAP v25.1&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Our Blazor Grid and TreeList will ship with PDF export APIs. This new functionality will allow you to generate PDF documents while preserving key data presentation elements, including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Column order, captions, and alignment&lt;/li&gt;
&lt;li&gt;Value format and alignment&lt;/li&gt;
&lt;li&gt;Group rows, group summaries, and group totals&lt;/li&gt;
&lt;li&gt;Total summaries&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We do not plan to support full WYSIWYG export, meaning that some UI elements (such as the group panel, search panel, toolbar, and pager, as well as custom CSS styles)&amp;nbsp;will be excluded.&lt;/p&gt;
&lt;h2 id="treelist"&gt;Blazor TreeList&lt;/h2&gt;
&lt;h3 id="search"&gt;Search&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Coming in v25.1&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We plan to add a built-in search box to our Blazor TreeList. You will be able to introduce search functionality with minimal configuration.&lt;/p&gt;
&lt;img src="https://community.devexpress.com/blogs/aspnet/v25.1/TreeList%20-%20Search%20Box.png" alt="treelist search"&gt;
&lt;h2 id="data-editors"&gt;Blazor Data Editors&lt;/h2&gt;
&lt;h3 id="dateedit-month-year-picker-view"&gt;Blazor Date Edit — Month/Year Picker View&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Coming in v25.1&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Our Blazor Date Edit will allow you to limit its selection to months or years. This can be useful for forms and fields that don&amp;#39;t require a specific date.&lt;/p&gt;
&lt;img src="https://community.devexpress.com/blogs/aspnet/v25.1/DateEdit%20-%20Month%20and%20Year%20picker%20view.png" alt="month year picker"&gt;
&lt;h3 id="listbox-select-all"&gt;Blazor List Box — Select All&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Coming in v25.1&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The DevExpress Blazor List Box will be able to display a &lt;code&gt;Select All&lt;/code&gt; check box above its items, allowing faster selection of multiple items.&lt;/p&gt;
&lt;img src="https://community.devexpress.com/blogs/aspnet/v25.1/Listbox%20-%20Select%20All.png" alt="list box select all"&gt;
&lt;h3 id="date-edit-time-edit-custom-increment-step"&gt;Blazor Date Edit &amp;amp; Time Edit — Custom Increment Step&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Coming in v25.1&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Time rollers in Blazor Date Edit and Time Edit components will support custom increment steps. This will allow you to display fewer values (e.g., an hour in 15 minute intervals) when precise selection isn&amp;#39;t necessary.&lt;/p&gt;
&lt;img src="https://community.devexpress.com/blogs/aspnet/v25.1/Roller%20-%20Increment%20Step.png" alt="roller intervals"&gt;
&lt;h2 id="map"&gt;Blazor Map&lt;/h2&gt;
&lt;h3 id="azure-maps-support"&gt;Azure Maps Support&lt;/h3&gt;&lt;p class="tags"&gt;&lt;span class="completed"&gt;Released in v24.2.5&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;As you know, Microsoft recently discontinued availability of &lt;a href="https://www.microsoft.com/en-us/maps/bing-maps/discontinued-services"&gt;Bing Maps for Enterprise and its associated APIs&lt;/a&gt;. &lt;a href="https://azure.microsoft.com/en-us/products/azure-maps/"&gt;Azure Maps&lt;/a&gt; will be Microsoft&amp;#39;s single unified enterprise mapping platform moving forward. Our Blazor Map UI component will support Azure Maps as a new map provider.&lt;/p&gt;
&lt;h2 id="pdf-viewer"&gt;Blazor PDF Viewer&lt;/h2&gt;
&lt;h3 id="set-download-name"&gt;Set Download Name&lt;/h3&gt;&lt;p class="tags"&gt;&lt;span class="completed"&gt;Released in v24.2.5&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Our new &lt;code&gt;DocumentName&lt;/code&gt; property will allow you to set a custom name for documents downloaded using the PDF Viewer’s toolbar command or via a &lt;code&gt;DownloadAsync&lt;/code&gt; method call.&lt;/p&gt;&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;DxPdfViewer DocumentName=&amp;quot;Sales Report&amp;quot; /&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="rich-text-editor"&gt;Blazor Rich Text Editor&lt;/h2&gt;
&lt;h3 id="zoom"&gt;Zoom&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Coming in EAP v25.1&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Our Blazor Rich Text Editor&amp;#39;s built-in Ribbon will include a UI to specify zoom level for the current document.&lt;/p&gt;
&lt;img class="small" src="https://community.devexpress.com/blogs/aspnet/v25.1/rich-zoom.png" alt="rich text editor zoom"&gt;
&lt;p&gt;It will also be possible to control the current zoom level using the Rich Text Editor&amp;#39;s API.&lt;/p&gt;
&lt;h2 id="scheduler"&gt;Blazor Scheduler&amp;nbsp;&lt;strong style="font-family:&amp;#39;Segoe UI&amp;#39;, &amp;#39;Helvetica Neue&amp;#39;, Helvetica, Arial, sans-serif;font-size:14px;"&gt;&lt;a href="https://supportcenter.devexpress.com/ticket/details/t1278694/feature-discussion-scheduler-blazor-roadmap-for-v25-1" target="_blank"&gt;(Discussion)&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;h3 id="toolbar-customization"&gt;Toolbar Customization&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Coming in EAP v25.1&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;In our upcoming release, we expect to support built-in toolbar customization. Our Scheduler will allow you to define custom toolbar items and customize the following built-in items:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Today button&lt;/li&gt;
&lt;li&gt;Next and Previous buttons&lt;/li&gt;
&lt;li&gt;Date navigator&lt;/li&gt;
&lt;li&gt;Resource navigator&lt;/li&gt;
&lt;li&gt;Scheduler View selector&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Customization options will include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Position and alignment of toolbar items.&lt;/li&gt;
&lt;li&gt;Enabled, Visible, Tooltip, and Render Style properties.&lt;/li&gt;
&lt;/ul&gt;&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;DxScheduler ...&amp;gt; 
    &amp;lt;ToolbarItems&amp;gt; 
        &amp;lt;DxSchedulerTodayToolbarItem /&amp;gt; 
        &amp;lt;DxSchedulerPreviousToolbarItem /&amp;gt; 
        &amp;lt;DxSchedulerNextToolbarItem /&amp;gt; 
        &amp;lt;DxToolbarItem Text=&amp;quot;Group by Resource&amp;quot; Click=&amp;quot;OnGroupByResourceClick&amp;quot; /&amp;gt; 
        &amp;lt;DxSchedulerResourceNavigatorToolbarItem /&amp;gt; 
    &amp;lt;/ToolbarItems&amp;gt; 
    ...
&amp;lt;DxScheduler&amp;gt; &lt;/code&gt;&lt;/pre&gt;
&lt;h3 id="resizing-and-dragging-for-appointment-form"&gt;Resizing and Dragging for Appointment Form&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Coming in EAP v25.1&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;End-users will be able to drag and resize our Blazor Scheduler&amp;#39;s &lt;a href="https://docs.devexpress.com/Blazor/404564/components/scheduler/customization/appointment-forms-and-tooltips#default-appointment-form"&gt;Appointment Edit Form&lt;/a&gt;, making it easier to view the rest of the calendar without discarding changes.&lt;/p&gt;
&lt;h3 id="appointment-form-customization"&gt;Appointment Form Customization&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Coming in EAP v25.1&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Our next update will introduce the following CSS classes:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;code&gt;AppointmentTooltipCssClass&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;&lt;code&gt;AppointmentCompactEditFormCssClass&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;&lt;code&gt;AppointmentEditFormCssClass&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These classes will allow you to customize appointment popup styles, including default values for width and height.&lt;/p&gt;
&lt;h3 id="popup-performance-enhancements"&gt;Appointment Popup Performance Enhancements&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Coming in EAP v25.1&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We plan to optimize the performance of our Scheduler&amp;#39;s dropdowns, forms, and tooltips (making them more responsive).&lt;/p&gt;
&lt;h3 id="ui-ux-enhancements"&gt;UI/UX Enhancements&lt;/h3&gt;
&lt;p class="tags"&gt;&lt;span class="completed"&gt;Coming in EAP v25.1&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We will introduce UI/UX enhancements designed to improve usability and overall appearance.&amp;nbsp;&lt;/p&gt;
&lt;h2 id="reporting"&gt;Blazor Reporting&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;Learn more:&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;a id="menur1m2v" href="https://community.devexpress.com/blogs/reporting/archive/2025/02/18/devexpress-reports-amp-bi-dashboard-june-2025-roadmap-v25-1.aspx" rel="noreferrer noopener" target="_blank" title="https://community.devexpress.com/blogs/reporting/archive/2025/02/18/devexpress-reports-amp-bi-dashboard-june-2025-roadmap-v25-1.aspx"&gt;DevExpress Reports &amp;amp; BI Dashboard — June 2025 Roadmap (v25.1)&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;Your Feedback Matters&lt;/h2&gt;
&lt;div data-survey-id="12b501a5-6d3a-418f-8c34-7feee55344bb" data-survey-auth-required="false"&gt;&lt;/div&gt;</description>
      <pubDate>Thu, 20 Feb 2025 10:00:00 Z</pubDate>
      <dc:creator>Alex Chuev (DevExpress)</dc:creator>
      <dx:excerpt>This post outlines key features/enhancements planned for our next major update (v25.1) in June 2025</dx:excerpt>
    </item>
    <item>
      <guid isPermaLink="false">bd716303-653c-428d-8b8a-a7d998cde032:388202</guid>
      <link>https://community.devexpress.com/Blogs/aspnet/archive/2024/10/04/asp.net-bootstrap-controls-bootstrap-xss-vulnerability-addressed.aspx</link>
      <category domain="https://community.devexpress.com/Tags/Bootstrap">Bootstrap</category>
      <category domain="https://community.devexpress.com/Tags/Bootstrap+version">Bootstrap version</category>
      <category domain="https://community.devexpress.com/Tags/Bootstrap5">Bootstrap5</category>
      <category domain="https://community.devexpress.com/Tags/dark+mode">dark mode</category>
      <category domain="https://community.devexpress.com/Tags/v24.2">v24.2</category>
      <title>ASP.NET Bootstrap Controls – Bootstrap XSS Vulnerability Addressed, Support for Bootstrap v5.3.3 and Dark Mode  </title>
      <description>&lt;p&gt;In this post, I&amp;#39;ll detail the upgrade of DevExpress&amp;nbsp;&lt;a href="https://www.devexpress.com/products/net/controls/asp/bootstrap-webforms.xml" target="_blank"&gt;Bootstrap controls&lt;/a&gt; to Bootstrap v5.3.3, enhanced security-related updates to DevExpress Bootstrap project templates, and support for color modes. &lt;/p&gt;
    
&lt;h2 id="project-templates"&gt;New Bootstrap Version in Project Templates: XSS Vulnerability Addressed&lt;/h2&gt; 

&lt;p&gt;DevExpress Bootstrap Controls are built atop&amp;nbsp;the Bootstrap framework and depend on static Bootstrap resources. Over the years,&amp;nbsp;DevExpress UI controls have supported&amp;nbsp;Bootstrap v3 – v5, and in the past,&amp;nbsp;DevExpress Bootstrap project templates have used Bootstrap v4.x. &lt;/p&gt;

&lt;p&gt;With v22.2 (and through v24.2), DevExpress project templates use Bootstrap v5 by default (including the most recent version of Bootstrap – v5.3.3). This upgrade is not merely cosmetic in nature. It addresses a critical security vulnerability in Bootstrap v4.0 - v4.6.2 (see&amp;nbsp;&lt;a href="https://github.com/advisories/GHSA-vc8w-jr9v-vj7f" target="_blank"&gt;Bootstrap Cross-Site Scripting (XSS) vulnerability&lt;/a&gt;). Though DevExpress UI controls do not directly use Bootstrap scripts, inadvertent use of JavaScript Bootstrap in other parts of a project could expose an application&amp;nbsp;to this vulnerability. Said simply, since the vulnerability was addressed in Bootstrap v5.0, our templates now use the most recent version of&amp;nbsp;Bootstrap.&lt;/p&gt;

&lt;h2 id="upgrade-existing-project"&gt;Upgrade Your Existing Project to v5&lt;/h2&gt; 


&lt;p&gt;Because of the XSS vulnerability in earlier versions of Bootstrap, we highly&amp;nbsp;recommend that you upgrade your existing Bootstrap project to v5 (to mitigate potential attack vectors and enhance the overall security posture of your application). To upgrade, you should:&amp;nbsp;&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;Update your Bootstrap files. Navigate to the &lt;a href="https://getbootstrap.com/" target="_blank"&gt;Bootstrap website&lt;/a&gt; and download the latest version. Replace old Bootstrap CSS and JS files in your project with new files. For additional information on&amp;nbsp;Bootstrap v5, please refer to  &lt;a href="https://getbootstrap.com/docs/5.0/migration/" target="_blank"&gt;Migrating to v5&lt;/a&gt;.&lt;/li&gt;
    &lt;li&gt;Set the Bootstrap mode setting to &lt;i&gt;Bootstrap5&lt;/i&gt; in your project&amp;#39;s &lt;b&gt;Web.Config&lt;/b&gt; file:
    &lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;configuration&amp;gt;
    ... 
    &amp;lt;devExpress&amp;gt;
            &amp;lt;bootstrap mode=&amp;quot;Bootstrap5&amp;quot; /&amp;gt;
    &amp;lt;/devExpress&amp;gt; 
    ... 
&amp;lt;/configuration&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id="dark-mode-support"&gt;Dark Mode Support&lt;/h2&gt; 
    
&lt;p&gt;Among the most exciting additions in newer versions of Bootstrap is built-in support for &lt;a href="https://getbootstrap.com/docs/5.3/customize/color-modes/" target="_blank"&gt;color modes&lt;/a&gt;. This feature allows developers to create applications that adapt to user preferences -&amp;nbsp;enhancing accessibility and the overall user experience. Since we updated Bootstrap resources to v5.3.3, our DevExpress Bootstrap controls now support color modes. For example, when you apply a Bootstrap-based theme, you can easily switch to &lt;a href="https://getbootstrap.com/docs/5.3/customize/color-modes/#dark-mode" target="_blank"&gt;dark mode&lt;/a&gt;. To incorporate this capability, add the &lt;i&gt;data-bs-theme&lt;/i&gt; attribute to the &lt;i&gt;&amp;lt;html&amp;gt;&lt;/i&gt; element.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;html lang=&amp;quot;en&amp;quot; data-bs-theme=&amp;quot;dark&amp;quot;&amp;gt;
    &amp;lt;head&amp;gt;
	   ... 
    &amp;lt;/head&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;As you can see in the image below, DevExpress UI controls fully integrate Bootstrap&amp;nbsp;styling, ensuring that your application&amp;nbsp;maintains a consistent look and feel.&lt;/p&gt;

&lt;img src="https://community.devexpress.com/blogs/aspnet/24.2/Bootstrap-controls-vulnerablitity-accessed/dark-mode.png" alt="Darrk Mode" style="width:780px;"&gt;


&lt;h2 id="what-about-blazor-components"&gt;What about Blazor components?&lt;/h2&gt; 

&lt;p&gt;The most recent versions of DevExpress Blazor UI&amp;nbsp;components (v24.1 and higher) do not rely on Bootstrap. However, they can use colors and other variables from Bootstrap themes. If you use Bootstrap in your Blazor projects, make certain to use Bootstrap v5.0 or higher. DevExpress Blazor components support Bootstrap v5.0 (v21.1) and Bootstrap v5.3 (v23.2+).&lt;/p&gt;
    
 
    
&lt;h2 id="have-questions"&gt;Have Questions?&lt;/h2&gt;
    &lt;p&gt;If you still have questions regarding the Bootstrap XSS vulnerability or its impact on DevExpress UI components, please submit a support ticket via the DevExpress&amp;nbsp;&lt;a href="https://supportcenter.devexpress.com/ticket/list" target="_blank"&gt;Support Center&lt;/a&gt;. We will be happy to follow up.&lt;/p&gt;</description>
      <pubDate>Fri, 04 Oct 2024 00:30:00 Z</pubDate>
      <dc:creator>Margarita Loseva (DevExpress)</dc:creator>
      <dx:excerpt>In this post, I&amp;#39;ll detail the upgrade of DevExpress Bootstrap controls to Bootstrap v5.3.3, enhanced security-related updates to DevExpress Bootstrap project templates, and support for color modes</dx:excerpt>
    </item>
  </channel>
</rss>