diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md
new file mode 100644
index 0000000000..eb5cfec430
--- /dev/null
+++ b/.github/copilot-instructions.md
@@ -0,0 +1,552 @@
+# Blazor Code Style Guide
+
+This guide outlines best practices for Razor component development and documentation in Blazor.
+
+## Razor File Structure
+
+Use the following top-down order in `.razor` files:
+
+1. `@page`
+2. `@using`
+3. `@namespace`
+4. `@inherits`
+5. `@implements`
+6. `@inject`
+
+Insert `
+
+@code {
+ private CompositeFilterDescriptor Value { get; set; } = new CompositeFilterDescriptor();
+ private string EventMessage { get; set; } = string.Empty;
+
+ private void OnFilterUpdate()
+ {
+ EventMessage = $"Filter updated at {DateTime.Now:HH:mm:ss}";
+ }
+
+ public class Person
+ {
+ public int EmployeeId { get; set; }
+ public string Name { get; set; } = string.Empty;
+ public int AgeInYears { get; set; }
+ }
+}
+````
+
## ValueChanged
The `ValueChanged` event fires when the value has changed. Its event handler receives the updated `CompositeFilterDescriptor` as an argument.
->caption Handle ValueChanged.
+> The `ValueChanged` event is deprecated and will be removed in future versions. Use the `OnUpdate` event instead.
+
+>caption Handle ValueChanged
````RAZOR
@* This code snippet showcases an example of how to handle the ValueChanged event. *@
diff --git a/components/form/formgroups.md b/components/form/formgroups.md
index 5ff7da282c..5919bfc08b 100644
--- a/components/form/formgroups.md
+++ b/components/form/formgroups.md
@@ -25,7 +25,7 @@ The `FormGroup` tag exposes the following parameters:
* `Columns` - `int` - defines the number of columns in the group.
-* `ColumnSpacing` - `string` - defines the space between the editors in the group.
+* `ColumnSpacing` - `string` - defines the horizontal space between the editors in the group.
## Example - Organize FormItems into Groups
@@ -51,7 +51,7 @@ You can organize some FormItems into logical groups. You can configure the label
-
+
diff --git a/components/form/overview.md b/components/form/overview.md
index 57643d1715..989fe67a82 100644
--- a/components/form/overview.md
+++ b/components/form/overview.md
@@ -207,7 +207,7 @@ The [Blazor Form](https://demos.telerik.com/blazor-ui/form/overview) exposes mul
|-----------|------------------------|-------------|
| `ButtonsLayout` | `FormButtonsLayout` enum (`Start`) | Determines the position and width of all Form buttons. See [Form Buttons](slug:form-formitems-buttons). |
| `Columns` | `int` | Defines the number of columns in the Form. See the [Columns](slug:form-columns) article for more information |
-| `ColumnSpacing` | `string` | Defines the amout of vertical space between the Columns. See the [Columns](slug:form-columns) article for more information. |
+| `ColumnSpacing` | `string` | Defines the amout of horizontal space between the Columns. See the [Columns](slug:form-columns) article for more information. |
| `Orientation` | `FormOrientation` enum (`Vertical`) | Determines the position of each label with regard to its editor. See [Orientation](slug:form-orientation) for more information. |
### Styling and Appearance
diff --git a/components/form/validation.md b/components/form/validation.md
index 81d5171fb5..f092d624ff 100644
--- a/components/form/validation.md
+++ b/components/form/validation.md
@@ -133,7 +133,6 @@ You can use the built-in `DataAnnotationsValidator` that comes with the Blazor f
-
@code {
public Person person { get; set; } = new Person();
@@ -158,8 +157,7 @@ You can use the
-````RAZOR
+````RAZOR.skip-repl
@using System.Dynamic
@using System.ComponentModel.DataAnnotations
@@ -228,50 +226,122 @@ When using a model with nested objects and fields, specify their `Field` setting
### Fluent Validation
-You can use third-party validation libraries that integrate with the standard `EditContext` such as FluentValidation together with the Telerik Form for Blazor.
+You can use third-party validation libraries that integrate with the standard `EditContext` such as [FluentValidation](https://fluentvalidation.net/) together with the Telerik Form for Blazor.
->note Such third party tools are not included with the Telerik UI for Blazor package. Your project must reference their NuGet packages explicitly. The code snippet below will not run unless you install the an appropriate package first. You can find some in their official documentation.
+The example below:
+* Requires the [`Blazored.FluentValidation` NuGet package](https://www.nuget.org/packages/Blazored.FluentValidation). Also refer to the [FluentValidation documentation](https://docs.fluentvalidation.net/en/latest/blazor.html).
+* Shows how to pass `ValueExpression` from a parent component to optional custom child components in a [Form item template](slug:form-formitems-template) or a [Grid editor template](slug:grid-templates-editor). If the `ValueExpression` is not passed correctly, the app will throw [exception similar to: `Cannot validate instances of type 'ComponentName'. This validator can only validate instances of type 'ModelClassName'`](slug:form-kb-fluent-validation-cannot-validate-instances-of-type).
>caption Using FluentValidation
-
-````RAZOR
-@using Microsoft.AspNetCore.Components.Forms
-@using FluentValidation
+````RAZOR Home.razor
@using Blazored.FluentValidation
+@using FluentValidation
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@FormSubmitResult
@code {
- public EditContext EditContext {get; set; }
- public Customer MyModel { get; set; } = new Customer();
- public CustomerValidator Validator { get; set; } = new CustomerValidator();
+ private Person PersonToEdit { get; set; } = new();
+
+ public PersonValidator PersonFluentValidator { get; set; } = new();
- protected override void OnInitialized()
+ private string FormSubmitResult { get; set; } = string.Empty;
+
+ private void LastNameChanged(string newLastName)
{
- EditContext = new EditContext(MyModel);
- base.OnInitialized();
+ PersonToEdit.LastName = newLastName;
}
- public class Customer
+ private void OnFormValidSubmit()
{
- public string FirstName { get; set; }
- public string LastName { get; set; }
+ FormSubmitResult = $"Form Submit Success at {DateTime.Now.ToString("HH:mm:ss")}";
+ }
+
+ public class PersonValidator : AbstractValidator
+ {
+ public PersonValidator()
+ {
+ RuleFor(customer => customer.FirstName).NotEmpty().MinimumLength(2).MaximumLength(60);
+ RuleFor(customer => customer.MiddleName).NotEmpty().MaximumLength(60);
+ RuleFor(customer => customer.LastName).NotEmpty().MinimumLength(2).MaximumLength(60);
+ }
+ }
+
+ public class Person
+ {
+ public int Id { get; set; }
+
+ public string FirstName { get; set; } = string.Empty;
+
+ public string MiddleName { get; set; } = string.Empty;
+
+ public string LastName { get; set; } = string.Empty;
}
+}
+````
+````RAZOR TextBox.razor
+@using System.Linq.Expressions
+
+
+
+@code {
+ [Parameter]
+ public string Value { get; set; } = string.Empty;
+
+ [Parameter]
+ public EventCallback ValueChanged { get; set; }
+
+ [Parameter]
+ public Expression>? ValueExpression { get; set; }
- public class CustomerValidator : AbstractValidator
+ [Parameter]
+ public string Id { get; set; } = string.Empty;
+
+ private async Task TextBoxValueChanged(string newValue)
{
- public CustomerValidator()
+ Value = newValue;
+
+ if (ValueChanged.HasDelegate)
{
- RuleFor(customer => customer.FirstName).NotEmpty().MaximumLength(50);
- RuleFor(customer => customer.LastName).NotEmpty().MaximumLength(50);
+ await ValueChanged.InvokeAsync(newValue);
}
}
}
diff --git a/components/gantt/gantt-tree/editing/incell.md b/components/gantt/gantt-tree/editing/incell.md
index a1b3e9d3ba..96e93d5a74 100644
--- a/components/gantt/gantt-tree/editing/incell.md
+++ b/components/gantt/gantt-tree/editing/incell.md
@@ -18,10 +18,18 @@ Command columns and non-editable columns are skipped while tabbing.
The InCell edit mode provides a specific user experience and behaves differently than other edit modes. Please review the notes below to get a better understanding of these specifics.
+## New Row Position
+
+To control whether a newly added item appears at the top or bottom of the Gantt Tree, set the `NewRowPosition` parameter.
+
+The `NewRowPosition` parameter accepts values from the `GanttTreeListNewRowPosition` enum:
+
+- `Top` (default)—Inserts the new item at the top of the view.
+- `Bottom`—Inserts the new item at the bottom of the view.
+
### Note
It is up to the data access logic to save the data once it is changed in the data collection, or to revert changes. The example above showcases the events that allow you to do that. In a real application, the code for handling data operations may be entirely different.
-
>caption InCell Editing Example.
````RAZOR
@@ -68,20 +76,9 @@ It is up to the data access logic to save the data once it is changed in the dat
@code {
- public DateTime SelectedDate { get; set; } = new DateTime(2019, 11, 11, 6, 0, 0);
-
- class FlatModel
- {
- public int Id { get; set; }
- public int? ParentId { get; set; }
- public string Title { get; set; }
- public double PercentComplete { get; set; }
- public DateTime Start { get; set; }
- public DateTime End { get; set; }
- }
-
- public int LastId { get; set; } = 1;
- List Data { get; set; }
+ private DateTime SelectedDate { get; set; } = new DateTime(2019, 11, 11, 6, 0, 0);
+ private int LastId { get; set; } = 1;
+ private List Data { get; set; }
protected override void OnInitialized()
{
@@ -122,6 +119,16 @@ It is up to the data access logic to save the data once it is changed in the dat
base.OnInitialized();
}
+ public class FlatModel
+ {
+ public int Id { get; set; }
+ public int? ParentId { get; set; }
+ public string Title { get; set; }
+ public double PercentComplete { get; set; }
+ public DateTime Start { get; set; }
+ public DateTime End { get; set; }
+ }
+
private async Task CreateItem(GanttCreateEventArgs args)
{
var argsItem = args.Item as FlatModel;
@@ -251,4 +258,3 @@ It is up to the data access logic to save the data once it is changed in the dat
## See Also
* [Live Demo: Gantt InCell Editing](https://demos.telerik.com/blazor-ui/gantt/editing-incell)
-
diff --git a/components/gantt/gantt-tree/editing/inline.md b/components/gantt/gantt-tree/editing/inline.md
index 55ca17ea03..690e11689c 100644
--- a/components/gantt/gantt-tree/editing/inline.md
+++ b/components/gantt/gantt-tree/editing/inline.md
@@ -20,6 +20,14 @@ You can also cancel the events by setting the `IsCancelled` property of the even
To enable Inline editing in the Gantt Tree, set its `TreeListEditMode` property to `GanttTreeListEditMode.Inline`, then handle the CRUD events as shown in the example below.
+## New Row Position
+
+To control whether a newly added item appears at the top or bottom of the Gantt Tree, set the `NewRowPosition` parameter.
+
+The `NewRowPosition` parameter accepts values from the `GanttTreeListNewRowPosition` enum:
+
+- `Top` (default)—Inserts the new item at the top of the view.
+- `Bottom`—Inserts the new item at the bottom of the view.
>caption The Command buttons and the Gantt events let you handle data operations in Inline edit mode.
@@ -70,20 +78,9 @@ To enable Inline editing in the Gantt Tree, set its `TreeListEditMode` property
@code {
- public DateTime SelectedDate { get; set; } = new DateTime(2019, 11, 11, 6, 0, 0);
-
- class FlatModel
- {
- public int Id { get; set; }
- public int? ParentId { get; set; }
- public string Title { get; set; }
- public double PercentComplete { get; set; }
- public DateTime Start { get; set; }
- public DateTime End { get; set; }
- }
-
- public int LastId { get; set; } = 1;
- List Data { get; set; }
+ private DateTime SelectedDate { get; set; } = new DateTime(2019, 11, 11, 6, 0, 0);
+ private int LastId { get; set; } = 1;
+ private List Data { get; set; }
protected override void OnInitialized()
{
@@ -124,6 +121,16 @@ To enable Inline editing in the Gantt Tree, set its `TreeListEditMode` property
base.OnInitialized();
}
+ public class FlatModel
+ {
+ public int Id { get; set; }
+ public int? ParentId { get; set; }
+ public string Title { get; set; }
+ public double PercentComplete { get; set; }
+ public DateTime Start { get; set; }
+ public DateTime End { get; set; }
+ }
+
private async Task CreateItem(GanttCreateEventArgs args)
{
var argsItem = args.Item as FlatModel;
diff --git a/components/gantt/gantt-tree/editing/overview.md b/components/gantt/gantt-tree/editing/overview.md
index b25d18813b..deacf14f0c 100644
--- a/components/gantt/gantt-tree/editing/overview.md
+++ b/components/gantt/gantt-tree/editing/overview.md
@@ -298,6 +298,30 @@ You can customize the editors rendered in the Gantt Tree by providing the `Edito
* `IsCanceled`- a boolean field indicating whether the operation is to be prevented.
+## New Row Position
+
+You can control whether a newly added item appears at the top or bottom of the Gantt Tree. Use the [`NewRowPosition`](https://www.telerik.com/blazor-ui/documentation/api/telerik.blazor.gantttreelistnewrowposition) parameter to specify the position. This parameter does not affect Popup edit mode, which always displays a dialog for new items.
+
+This configuration is available in InCell and Inline edit modes. For more details, see the [Tree InCell Editing](slug:gant-tree-incell-editing#new-row-position) and [Tree Inline Editing](slug:gant-tree-inline-editing#new-row-position) articles.
+
+> When you set `NewRowPosition` to `Bottom`, add the new item at the end of your data collection in the `OnCreate` event handler. When set to `Top`, insert the new item at the beginning of the collection. This ensures the new row appears in the correct position in the view after successfully creating the new record.
+
+>caption Example of adding a new item to the Gantt based on the `NewRowPosition` value
+
+
+````C#
+private void OnCreate(GanttCreateEventArgs args)
+{
+ if (NewRowPosition == GanttTreeListNewRowPosition.Bottom)
+ {
+ dataCollection.Add(newItem);
+ }
+ else // Top
+ {
+ dataCollection.Insert(0, newItem);
+ }
+}
+````
## Example
diff --git a/components/gauges/arc/labels.md b/components/gauges/arc/labels.md
index 48ece6bda1..0455af3ed6 100644
--- a/components/gauges/arc/labels.md
+++ b/components/gauges/arc/labels.md
@@ -13,13 +13,10 @@ position: 20
You can customize the appearance of the labels rendered on the [scale](slug:arc-gauge-scale) of the Arc Gauge by using the ``, child tag of the ``, and the parameters it exposes:
* [Format](#format)
-
* [Center Template](#center-template)
-
+* [Position](#position)
* [Color](#color)
-
* [Visible](#visible)
-
* [Additional Customization](#additional-customization)
## Format
@@ -87,6 +84,42 @@ The center template allows you to take control of the rendering of the central s
````
+## Position
+
+The `Position` parameter is of enum type `ArcGaugeScaleLabelsPosition` and determines whether the Gauge labels are on the inside (default) or outside of the Gauge graphic. Labels on the inside allow for a visually larger component within the same available space.
+
+>caption Setting Arc Gauge label position
+
+````RAZOR
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+````
+
## Color
The `Color` (`string`) parameter controls the color of the labels. It accepts **CSS**, **HEX** and **RGB** colors.
diff --git a/components/gauges/circular/labels.md b/components/gauges/circular/labels.md
index d5eca523e7..5551dc9714 100644
--- a/components/gauges/circular/labels.md
+++ b/components/gauges/circular/labels.md
@@ -13,13 +13,10 @@ position: 15
You can customize the appearance of the labels rendered on the [scale](slug:circular-gauge-scale) of the Circular Gauge by using the ``, child tag of the ``, and the parameters it exposes:
* [Format](#format)
-
* [Center Template](#center-template)
-
+* [Position](#position)
* [Color](#color)
-
* [Visible](#visible)
-
* [Additional Customization](#additional-customization)
## Format
@@ -91,6 +88,42 @@ The center template allows you to take control of the rendering of the central s
````
+## Position
+
+The `Position` parameter is of enum type `CircularGaugeScaleLabelsPosition` and determines whether the Gauge labels are on the inside (default) or outside of the Gauge graphic. Labels on the inside allow for a visually larger component on the same available space.
+
+>caption Setting Circular Gauge label position
+
+````RAZOR
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+````
+
## Color
The `Color` (`string`) parameter controls the color of the labels. It accepts **CSS**, **HEX** and **RGB** colors.
diff --git a/components/grid/editing/incell.md b/components/grid/editing/incell.md
index 570f0a1c36..b4dd5155e2 100644
--- a/components/grid/editing/incell.md
+++ b/components/grid/editing/incell.md
@@ -54,6 +54,17 @@ In in-cell edit mode, the `OnAdd` and `OnCreate` events fire immediately one aft
The above algorithm is different from [inline](slug:grid-editing-inline) and [popup](slug:grid-editing-popup) editing where new rows are only added to the data source after users populate them with valid values.
+## New Row Position
+
+You can control whether a newly added item appears at the top or bottom of the Grid. Use the `NewRowPosition` parameter to specify the position.
+
+The `NewRowPosition` parameter accepts values from the `GridNewRowPosition` enum:
+
+- `Top` (default)—Inserts the new item at the top of the view.
+- `Bottom`—Inserts the new item at the bottom of the view.
+
+For a complete example of how this feature works, see the following [example](slug:grid-editing-incell#basic).
+
## Integration with Other Features
Here is how the component behaves when the user tries to use add and edit operations together with other component features. Also check the [common information on this topic for all edit modes](slug:grid-editing-overview#integration-with-other-features).
@@ -72,6 +83,8 @@ This section explains what happens when the user tries to perform another data o
* If the validation is satisfied, then editing completes and the component fires `OnUpdate`.
* If the validation is not satisfied, then editing aborts and the component fires `OnCancel`.
+Deleting items that are currently in edit mode [fires `OnDelete` with a cloned data item instance](slug:grid-editing-overview#delete-operations).
+
### Selection
To enable [row selection](slug:grid-selection-row) with in-cell edit mode, use a [checkbox column](slug:components/grid/columns/checkbox). More information on that can be read in the [Row Selection](slug:grid-selection-row#selection-and-editing-modes) article.
diff --git a/components/grid/editing/inline.md b/components/grid/editing/inline.md
index 047e99ba57..a8022b2902 100644
--- a/components/grid/editing/inline.md
+++ b/components/grid/editing/inline.md
@@ -37,7 +37,16 @@ Inline add, edit, and delete operations use the following [command buttons](slug
In inline edit mode, the Grid commands execute row by row and the corresponding [Grid events](slug:grid-editing-overview#events) also fire row by row. This is similar to [popup editing](slug:grid-editing-popup) and unlike [in-cell editing](slug:grid-editing-incell), where commands and events relate to cells.
-When validation is not satisfied, clicking the **Save**, **Delete** or **Add** command buttons has no effect, but users can still navigate between all input components in the row to complete the editing.
+When validation is not satisfied, clicking the **Save**, **Delete** or **Add** command buttons have no effect, but users can still navigate between all input components in the row to complete the editing.
+
+## New Row Position
+
+You can control whether a newly added item appears at the top or bottom of the Grid. Use the `NewRowPosition` parameter to specify the position.
+
+The `NewRowPosition` parameter accepts values from the `GridNewRowPosition` enum:
+
+- `Top` (default)—Inserts the new item at the top of the view.
+- `Bottom`—Inserts the new item at the bottom of the view.
## Integration with Other Features
@@ -54,6 +63,8 @@ This section explains what happens when the component is already in add or edit
If the component is already in add or edit mode, and the user tries to perform another data operation, then editing aborts and the component fires `OnCancel`.
+Deleting items that are currently in edit mode [fires `OnDelete` with a cloned data item instance](slug:grid-editing-overview#delete-operations).
+
## Examples
### Basic
diff --git a/components/grid/editing/overview.md b/components/grid/editing/overview.md
index ead20360ca..02f76a10e7 100644
--- a/components/grid/editing/overview.md
+++ b/components/grid/editing/overview.md
@@ -35,6 +35,7 @@ The Grid CRUD operations rely on the following algorithm:
Adding or editing rows in the Grid sets the following requirements on the Grid model:
* The Grid model class must have a parameterless constructor. Otherwise, use the [Grid `OnModelInit` event](slug:grid-events#onmodelinit) to provide a data item instance [when the Grid needs to create one](#item-instances). Optinally, you can also [set some default values](slug://grid-kb-default-value-for-new-row).
+* There must be a non-editable property that serves as a unique identifier.
* All editable properties must be `public` and have setters. These properties must not be `readonly`.
* All complex properties used in the Grid must be instantiated in the [Grid `OnModelInit` event](slug:grid-events#onmodelinit).
* Self-referencing or inherited properties must not cause `StackOverflowException` or `AmbiguousMatchException` during [programmatic model instance creation](#item-instances).
@@ -79,6 +80,8 @@ Delete operations provide the same user experience in all Grid edit modes and re
Delete operations can work even if the Grid `EditMode` parameter value is `None`.
+If the Grid contains Delete command buttons that display and operate in edit mode, these buttons will fire the [`OnDelete` event](#events) with a [cloned data item instance](#item-instances) in the [event argument](#gridcommandeventargs). To find the original data item in the Grid data source, use the item ID or [override the `Equals()` method of the Grid model class](slug://grid-kb-editing-in-hierarchy).
+
>tip See the delete operations in action in the complete examples for Grid [inline](slug:grid-editing-inline#examples), [in-cell](slug:grid-editing-incell#examples), and [popup](slug:grid-editing-popup#examples) editing. Also check how to [customize the Delete Confirmation Dialog](slug:grid-kb-customize-delete-confirmation-dialog).
## Commands
@@ -97,7 +100,9 @@ Users execute commands in the following ways:
* By clicking on editable cells in [in-cell edit mode](slug:grid-editing-incell) and then anywhere else on the page.
* By using the [Grid keyboard navigation](https://demos.telerik.com/blazor-ui/grid/keyboard-navigation).
-Command buttons can only reside in a [Grid Command Column](slug:components/grid/columns/command) or the [Grid ToolBar](slug:components/grid/features/toolbar). You can also [trigger add and edit operations programmatically](slug:grid-kb-add-edit-state) from anywhere on the web page through the [Grid State](slug:grid-state).
+Command buttons can only reside in a [Grid Command Column](slug:components/grid/columns/command) or the [Grid ToolBar](slug:components/grid/features/toolbar). Each command button in the command column is visible only in display mode or only in edit mode, depending on the button's `ShowInEdit` boolean parameter value.
+
+You can also [trigger add and edit operations programmatically](slug:grid-kb-add-edit-state) from anywhere on the web page through the [Grid State](slug:grid-state).
## Events
@@ -110,7 +115,7 @@ The following table describes the Grid events, which are related to adding, dele
| `OnAdd` | No | Fires on `Add` [command button](slug://components/grid/columns/command) click, before the Grid enters add mode. This event preceeds `OnCreate` or `OnCancel`. | [New](#item-instances) | Grid remains in read mode. |
| `OnCancel` | No | Fires on `Cancel` command invocation. | [New or cloned](#item-instances) | Grid remains in add or edit mode. |
| `OnCreate` | To add new items. | Fires on `Save` command invocation for new items. This event succeeds `OnAdd`. | [New](#item-instances) | Grid remains in add mode. |
-| `OnDelete` | To [delete items](#delete-operations). | Fires on `Delete` command button click. | Original | Grid won't rebind. Deletion depends on the app itself. |
+| `OnDelete` | To [delete items](#delete-operations). | Fires on `Delete` command button click. | [Original or cloned](#item-instances) | Grid won't rebind. Deletion depends on the app itself. |
| `OnEdit` | No | Fires on `Edit` command invocation, before the Grid actually enters edit mode. This event preceeds `OnUpdate` or `OnCancel`. | Original | Grid remains in read mode. |
| `OnModelInit` | [Depends on the Grid model type](slug:grid-events#onmodelinit) | Fires when the Grid requires a [new model instance](#item-instances), which is immediately before `OnAdd` or immediately after `OnEdit`. Use this event when the Grid model type is an [interface, abstract class, or has no parameterless constructor](slug:grid-events#onmodelinit). | No event arguments | Not cancellable |
| `OnUpdate` | To edit existing items. | Fires on `Save` command invocation for existing items. This event succeeds `OnEdit`. | [Cloned](#item-instances) | Grid remains in edit mode. |
@@ -200,6 +205,32 @@ When editing a master row in a [hierarchy Grid](slug://components/grid/features/
Learn more integration details for the [inline](slug:grid-editing-inline#integration-with-other-features) and [in-cell](slug:grid-editing-incell#integration-with-other-features) edit modes.
+
+## New Row Position
+
+You can control whether a newly added item appears at the top or bottom of the Grid. Use the [`NewRowPosition`](https://www.telerik.com/blazor-ui/documentation/api/telerik.blazor.gridnewrowposition) parameter to specify the position. This parameter does not affect Popup edit mode, which always displays a dialog for new items.
+
+This configuration is available in InCell and Inline edit modes. For more details, see the [InCell Editing](slug:grid-editing-incell#new-row-position) and [Inline Editing](slug:grid-editing-inline#new-row-position) articles.
+
+> When you set `NewRowPosition` to `Bottom`, add the new item at the end of your data collection in the `OnCreate` event handler. When set to `Top`, insert the new item at the beginning of the collection. This ensures the new row appears in the correct position in the view after successfully creating the new record.
+
+>caption Example of adding a new item to the Grid based on the `NewRowPosition` value
+
+
+````C#
+private void OnCreate(GridCommandEventArgs args)
+{
+ if (NewRowPosition == GridNewRowPosition.Bottom)
+ {
+ dataCollection.Add(newItem);
+ }
+ else // Top
+ {
+ dataCollection.Insert(0, newItem);
+ }
+}
+````
+
## Examples
See Grid CRUD operations in action at:
diff --git a/components/grid/highlighting.md b/components/grid/highlighting.md
new file mode 100644
index 0000000000..84b09f5729
--- /dev/null
+++ b/components/grid/highlighting.md
@@ -0,0 +1,116 @@
+---
+title: Highlighting
+page_title: Grid Highlighting
+slug: grid-highlighting
+description: Highlight rows and cells in the Telerik Blazor Grid to draw attention to important data.
+tags: telerik,blazor,grid,highlight,highlighting
+published: true
+position: 40
+---
+
+# Blazor Grid Highlighting
+
+The Telerik Blazor Grid enables you to highlight rows and cells programmatically. Use highlighting to draw attention to important data, indicate status, or visually group related records. Highlighting does not require user interaction and is fully controlled by the application logic.
+
+## Key Features
+
+* Highlight entire rows by providing a list of data items.
+* Highlight individual cells by specifying the data item and column.
+* Combine row and cell highlighting.
+* Highlighting uses a visual style similar to selection, but does not affect selection state or user interaction.
+
+To see the Grid highlighting in action, check the below [example](#example).
+
+## API Reference
+
+The Grid highlighting feature exposes the following parameters:
+
+- `HighlightedItems`—Highlight entire rows by providing the data items to highlight. The list must contain references to items from the grid's data source, not new instances.
+- `HighlightedCells`—Highlight individual cells by specifying both the data item and the column field. Both values must match the Grid data and column definitions.
+
+See [Grid Highlighting API Reference](slug:telerik.blazor.components.gridhighlighting) for details about these parameters and the `GridHighlightedCellDescriptor` type.
+
+## Example
+
+>caption Example of highlighting rows and cells in the Blazor Grid
+
+````RAZOR
+
+
+
+
+
+
+
+
+
+
+
+@code {
+ private List GridData { get; set; } = new();
+ private List HighlightedItems { get; set; } = new();
+ private List HighlightedCells { get; set; } = new();
+
+ protected override void OnInitialized()
+ {
+ GenerateData();
+ SetHighlight();
+ }
+
+ private void SetHighlight()
+ {
+ // Highlight 5 items starting from the 3rd item in the data list
+ HighlightedItems = GridData.Skip(2).Take(5).ToList();
+
+ // Highlight specific cells: the ProductName of the first item and Discounted of the second item
+ HighlightedCells = new List
+ {
+ new GridHighlightedCellDescriptor
+ {
+ ColumnField = nameof(Product.ProductName),
+ DataItem = GridData[0]
+ },
+ new GridHighlightedCellDescriptor
+ {
+ ColumnField = nameof(Product.Discontinued),
+ DataItem = GridData[1]
+ }
+ };
+ }
+
+ private void GenerateData()
+ {
+ var random = new Random();
+ for (int i = 1; i <= 20; i++)
+ {
+ GridData.Add(new Product
+ {
+ ProductId = i,
+ ProductName = $"Product {i}",
+ UnitPrice = Math.Round(random.NextDouble() * 100, 2),
+ UnitsInStock = random.Next(1, 100),
+ CreatedAt = DateTime.Now.AddDays(-random.Next(1, 100)),
+ Discontinued = i % 5 == 0
+ });
+ }
+ }
+
+ public class Product
+ {
+ public int ProductId { get; set; }
+ public string ProductName { get; set; } = string.Empty;
+ public double UnitPrice { get; set; }
+ public int UnitsInStock { get; set; }
+ public DateTime CreatedAt { get; set; }
+ public bool Discontinued { get; set; }
+ }
+}
+````
+
+## See Also
+
+* [Grid Selection](slug:grid-selection-overview)
+* [Highlighting API Reference](slug:telerik.blazor.components.gridhighlighting)
\ No newline at end of file
diff --git a/components/grid/overview.md b/components/grid/overview.md
index 1fdb9de86b..ff65765d96 100644
--- a/components/grid/overview.md
+++ b/components/grid/overview.md
@@ -5,6 +5,7 @@ description: The Blazor Grid provides a comprehensive set of ready-to-use featur
slug: grid-overview
tags: telerik,blazor,grid,datagrid,overview
published: True
+hideCta: True
position: 0
---
@@ -12,6 +13,8 @@ position: 0
This article provides a quick introduction to get your first Blazor data grid component up and running in a few seconds. There is a video tutorial and a list of the key features.
+Tired of reading docs? With our new AI Coding Assistants, you can add, configure, and troubleshoot Telerik UI for Blazor components—right inside your favorite AI-powered IDE: Visual Studio, VS Code, Cursor, and more. Start building faster, smarter, and with contextual intelligence powered by our docs/APIs:Try AI Assistants
+
The Telerik Blazor Data Grid provides a comprehensive set of ready-to-use features that cover everything from paging, sorting, filtering, editing, and grouping to row virtualization, optimized data reading, keyboard navigation, and accessibility support.
The Telerik Blazor grid is built on native Blazor from the ground up, by a company with a long history of making enterprise-ready Grids. This results in a highly customizable Grid that delivers lighting fast performance.
@@ -151,6 +154,7 @@ The Grid supports custom content in various parts of the component such as data
* [Drag and drop rows](slug:grid-drag-drop-overview)—move rows in a Grid or between different Grids.
* [Loading animation](slug:grid-loading)—show a loading animation to improve user experience during long data operations.
* Scrolling—the Grid will show standard scrollbars automatically if the data does not fit the current component width and height.
+* [Highlighting](slug:grid-highlighting)—highlight rows or cells programmatically to draw attention to important data.
## Grid Parameters
diff --git a/components/grid/selection/cells.md b/components/grid/selection/cells.md
index d57d3fd55e..d90f54bdbe 100644
--- a/components/grid/selection/cells.md
+++ b/components/grid/selection/cells.md
@@ -237,3 +237,4 @@ When using [Grid templates](slug:components/grid/features/templates) with cell s
* [Live Demo: Grid Cell Selection](https://demos.telerik.com/blazor-ui/grid/cell-selection)
* [Blazor Grid](slug:grid-overview)
+* [Grid Highlighting](slug:grid-highlighting)
diff --git a/components/grid/selection/rows.md b/components/grid/selection/rows.md
index 567060fce3..ed3fcef7a0 100644
--- a/components/grid/selection/rows.md
+++ b/components/grid/selection/rows.md
@@ -213,3 +213,4 @@ The Grid clears the `SelectedItems` collection when the user drags and drops sel
* [Live Demo: Grid Row Selection](https://demos.telerik.com/blazor-ui/grid/row-selection)
* [Blazor Grid](slug:grid-overview)
+* [Grid Highlighting](slug:grid-highlighting)
diff --git a/components/grid/state.md b/components/grid/state.md
index 049bc989f1..fb6c7f7b6d 100644
--- a/components/grid/state.md
+++ b/components/grid/state.md
@@ -43,7 +43,7 @@ The Grid state is a generic [class `GridState`](slug:Telerik.Blazor.Compo
| `SelectedItems` | `ICollection` | The currently [selected data item(s)](slug:grid-selection-overview). |
| `Skip` | `int?` | The number of scrolled data items when using [virtual row scrolling](slug:components/grid/virtual-scrolling). In other words, this is the number of rows above the currently visible ones. |
| `SortDescriptors` | `ICollection` | The currently applied [sorts](slug:components/grid/features/sorting). |
-| `TableWidth` | `string` | The sum of all visible column widths. This property changes together with `ColumnStates`. The `OnStateChanged` event does not fire separately for it. |
+| `TableWidth` | `string` | The sum of all visible column widths. The initial value is always `null` regardless of the column configuration. The `TableWidth` value changes during column resizing together with `ColumnStates` and the`OnStateChanged` event does not fire separately for it. When you resize a column programmatically, and all other columns already have widths, you must update the `TableWidth` too, otherwise the other columns will resize unexpectedly. |
\* `TItem` is the Grid model type.
diff --git a/components/grid/templates/editor.md b/components/grid/templates/editor.md
index 88c46218e8..d7e769dbf2 100644
--- a/components/grid/templates/editor.md
+++ b/components/grid/templates/editor.md
@@ -20,12 +20,13 @@ If you need more complex logic inside the editor template, compared to simple da
>tip The Editor Template works in all edit modes (Inline, Popup, InCell). Before using it with InCell mode, review the [pertinent notes](slug:grid-editing-incell#editor-template).
-When an input receives an `EditContext` (usually comes down as a cascading parameter), the framework also requires a `ValueExpression`. If you use two-way binding (the `@bind-Value` syntax), the `ValueExpression` is deducted from there. However, if you use only the `Value` property, you have to pass the `ValueExpression` yourself. This is a lambda expression that tells the framework what field in the model to update. The following sample demonstrates how to achieve that. You can also check the [Requires a value for ValueExpression](slug://common-kb-requires-valueexpression) knowledge base article for more details.
+When an input receives an `EditContext` (usually as a cascading parameter), the framework also requires a `ValueExpression`. If you use two-way binding (the `@bind-Value` syntax), the `ValueExpression` is deducted from there. However, if you use only the `Value` parameter, you have to pass the `ValueExpression` explicitly. This is a lambda expression that tells the framework what property of the model to use for validation. The following sample demonstrates how to achieve that. You can also check the [Requires a value for ValueExpression](slug:common-kb-requires-valueexpression) knowledge base article for more details.
````RAZOR
@@ -33,7 +34,6 @@ When an input receives an `EditContext` (usually comes down as a cascading param
@* Applies to the other input type components as well *@
````
-
**In this article:**
* [Notes](#notes)
@@ -46,39 +46,30 @@ When an input receives an `EditContext` (usually comes down as a cascading param
* @[template](/_contentTemplates/common/inputs.md#edit-debouncedelay)
-* The Grid row creates an `EditContext` and passes it to the `EditorTemplate`. You can read more about it in the [**Notes** section of the Editing Overview](slug:grid-editing-overview#notes) article.
-
* We recommend casting the Editor Template context to your model and storing it in a local or a dedicated global variable. Do not share a global variable within multiple templates, like column (cell) template and editor template. Variable sharing can lead to unexpected behavior.
-* Direct casting of the `context` can make the data binding not work properly.
-
-
->caption Not recommended: direct casting. Binding does not work properly.
+* Direct casting of the `context` can make two-way data binding not work properly.
-
+>caption Not recommended: direct casting with two-way parameter binding
-````RAZOR
+````RAZOR.skip-repl
````
->caption Recommended: cast the context to your model type and store it in a variable. Binding works as expected.
+>caption Recommended: cast the context in advance
````RAZOR
@{
- EditedProduct = context as Product;
+ var editProduct = (Product)context;
-
+
}
-
-@code{
- private Product EditedProduct { get; set; }
-}
````
## Examples
diff --git a/components/multicolumncombobox/data-bind.md b/components/multicolumncombobox/data-bind.md
index fa4826e313..2ccbc89eb6 100644
--- a/components/multicolumncombobox/data-bind.md
+++ b/components/multicolumncombobox/data-bind.md
@@ -53,7 +53,7 @@ Missing selection is most common when:
## Missing Value or Data
-The MultiColumnCombobox component attempts to infer the type of its model and value based on the provided `Data` and initial `Value`. This affects its [object reference](slug:multicolumncombobox-overview#component-reference-and-methods).
+The MultiColumnCombobox component attempts to infer the type of its model and value based on the provided `Data` and initial `Value`. This affects its [object reference](slug:common-features-data-binding-overview#component-type).
In case you cannot provide either the `Value` or `Data` initially, you need to [set the corresponding types to the `TItem` and `TValue` parameters](slug:common-features-data-binding-overview#component-type).
diff --git a/components/multicolumncombobox/overview.md b/components/multicolumncombobox/overview.md
index 313e883c97..ea6b2b9cd8 100644
--- a/components/multicolumncombobox/overview.md
+++ b/components/multicolumncombobox/overview.md
@@ -166,11 +166,7 @@ The MultiColumnComboBox provides the following popup settings:
## Component Reference and Methods
-To execute MultiColumnComboBox methods, obtain reference to the component instance via `@ref`.
-
-The MultiColumnComboBox is a generic component. Its type depends on the type of its model and the type of its `Value`. In case you cannot provide either the `Value` or `Data` initially, you need to [set the corresponding types to the `TItem` and `TValue` parameters](slug:common-features-data-binding-overview#component-type).
-
-The table below lists the MultiComboBox methods. Also consult the [MultiColumnComboBox API](slug:Telerik.Blazor.Components.TelerikMultiColumnComboBox-2).
+Add a reference to the component instance to use the [MultiColumnComboBox's methods](slug:Telerik.Blazor.Components.TelerikMultiColumnComboBox-2). Note that the [MultiColumnComboBox is a generic component](slug:common-features-data-binding-overview#component-type).
| Method | Description |
| --- | --- |
diff --git a/components/multiselect/data-bind.md b/components/multiselect/data-bind.md
index 6000ec15c2..d21e142013 100644
--- a/components/multiselect/data-bind.md
+++ b/components/multiselect/data-bind.md
@@ -128,57 +128,7 @@ To bind the MultiSelect to a model:
## Considerations
-The MultiSelect component attempts to infer the type of its model and value based on the provided `Data` and initial `Value`. This affects the way its [reference is obtained](#reference) and what happens [if you can't provide data or a value](#missing-value-or-data).
-
-### Reference
-
-The MultiSelect is a generic component and its type depends on the type of its `Data` and `Value`.
-
-
-````RAZOR String
-@*Reference type when binding to a string collection*@
-
-
-
-@code {
- private TelerikMultiSelect? MultiSelectRef { get; set; }
-
- private List MultiSelectValue { get; set; } = new();
-
- private List MultiSelectData { get; set; } = new List { "first", "second", "third" };
-}
-````
-````RAZOR Model
-@*Reference when binding to a model collection*@
-
-
-
-@code {
- private TelerikMultiSelect? MultiSelectRef { get; set; }
-
- private List MultiSelectValue { get; set; } = new();
-
- private List MultiSelectData { get; set; } = new List()
- {
- new MultiSelectItem { Text = "first", Value = 1 },
- new MultiSelectItem { Text = "second", Value = 2 },
- new MultiSelectItem { Text = "third", Value = 3 }
- };
-
- public class MultiSelectItem
- {
- public string Text { get; set; } = string.Empty;
-
- public int Value { get; set; }
- }
-}
-````
+The MultiSelect component attempts to infer the type of its model and value based on the provided `Data` and initial `Value`. This affects the way its [reference is obtained](slug:common-features-data-binding-overview#component-type) and what happens [if you can't provide data or a value](#missing-value-or-data).
### Missing Value Or Data
diff --git a/components/multiselect/overview.md b/components/multiselect/overview.md
index f95842f7f3..734da0ac2b 100644
--- a/components/multiselect/overview.md
+++ b/components/multiselect/overview.md
@@ -14,47 +14,63 @@ The Blaz
## Creating MultiSelect
-1. Use the `TelerikMultiSelect` tag to add the component to your razor page.
+1. Add the `TelerikMultiSelect` tag to your razor page.
+1. [Bind the `Data` parameter to the collection of objects or strings](slug:multiselect-databind) that you want to appear in the dropdown.
+1. Set the `TextField` parameter to point to the object property that holds the user-readable value.
+1. Set the `ValueField` parameter to point to the object property that holds the data item value.
+1. [Bind the `Value` of the component](slug:get-started-value-vs-data-binding#value-binding) to a collection of the same type as the type defined by the `ValueField` parameter.
+1. (optional) Configure additional features like `AutoClose`, `Placeholder`, or `ShowClearButton`.
-1. Populate the `Data` property with the collection of items that you want to appear in the dropdown.
-
-1. [Bind the value of the component](slug:get-started-value-vs-data-binding#value-binding) to a collection of the same type as the type defined in the `ValueField` parameter.
-
-1. (Optional) Enable features like placeholder text, clear button, and AutoClose.
-
->caption MultiSelect two-way value binding, main features, and simple [data binding](slug:multiselect-databind)
+>caption Basic Blazor MultiSelect two-way value binding, main features, and simple [data binding](slug:multiselect-databind)
````RAZOR
-@* Main features and simple data binding for the suggestions and the Value *@
+ @bind-Value="@MultiSelectValues"
+ TextField="@nameof(Country.Name)"
+ ValueField="@nameof(Country.Id)"
+ AutoClose="false"
+ Placeholder="Select Balkan Countries"
+ ShowClearButton="true">
-@if (Values.Count > 0)
+
+@if (MultiSelectValues.Count > 0)
{