Skip to content

Commit

Permalink
Merge pull request #31935 from dotnet/main
Browse files Browse the repository at this point in the history
  • Loading branch information
guardrex authored Feb 29, 2024
2 parents 49e5bd6 + 84d323f commit 02c63b5
Show file tree
Hide file tree
Showing 13 changed files with 216 additions and 61 deletions.
38 changes: 18 additions & 20 deletions aspnetcore/blazor/components/quickgrid.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ uid: blazor/components/quickgrid

:::moniker range=">= aspnetcore-8.0"

<!-- UPDATE 8.0 No API doc for Quickgrid and Microsoft.AspNetCore.Components.QuickGrid -->

The `QuickGrid` component is a Razor component for quickly and efficiently displaying data in tabular form. `QuickGrid` provides a simple and convenient data grid component for common grid rendering scenarios and serves as a reference architecture and performance baseline for building data grid components. `QuickGrid` is highly optimized and uses advanced techniques to achieve optimal rendering performance.
The [`QuickGrid`](xref:Microsoft.AspNetCore.Components.QuickGrid) component is a Razor component for quickly and efficiently displaying data in tabular form. `QuickGrid` provides a simple and convenient data grid component for common grid rendering scenarios and serves as a reference architecture and performance baseline for building data grid components. `QuickGrid` is highly optimized and uses advanced techniques to achieve optimal rendering performance.

[!INCLUDE[](~/blazor/includes/location-client-and-server-pre-net8.md)]

Expand All @@ -36,21 +34,21 @@ To implement a `QuickGrid` component:

* Specify tags for the `QuickGrid` component in Razor markup (`<QuickGrid>...</QuickGrid>`).
* Name a queryable source of data for the grid. Use ***either*** of the following data sources:
* `Items`: A nullable `IQueryable<TGridItem>`, where `TGridItem` is the type of data represented by each row in the grid.
* `ItemsProvider`: A callback that supplies data for the grid.
* `Class`: An optional CSS class name. If provided, the class name is included in the `class` attribute of the rendered table.
* `Theme`: A theme name (default value: `default`). This affects which styling rules match the table.
* `Virtualize`: If true, the grid is rendered with virtualization. This is normally used in conjunction with scrolling and causes the grid to fetch and render only the data around the current scroll viewport. This can greatly improve the performance when scrolling through large data sets. If you use `Virtualize`, you should supply a value for `ItemSize` and must ensure that every row renders with a constant height. Generally, it's preferable not to use `Virtualize` if the amount of data rendered is small or if you're using pagination.
* `ItemSize`: Only applicable when using `Virtualize`. `ItemSize` defines an expected height in pixels for each row, allowing the virtualization mechanism to fetch the correct number of items to match the display size and to ensure accurate scrolling.
* `ItemKey`: Optionally defines a value for `@key` on each rendered row. Typically, this is used to specify a unique identifier, such as a primary key value, for each data item. This allows the grid to preserve the association between row elements and data items based on their unique identifiers, even when the `TGridItem` instances are replaced by new copies (for example, after a new query against the underlying data store). If not set, the `@key` is the `TGridItem` instance.
* `Pagination`: Optionally links this `TGridItem` instance with a `PaginationState` model, causing the grid to fetch and render only the current page of data. This is normally used in conjunction with a `Paginator` component or some other UI logic that displays and updates the supplied `PaginationState` instance.
* In the `QuickGrid` child content (<xref:Microsoft.AspNetCore.Components.RenderFragment>), specify `PropertyColumn`s, which represent `TGridItem` columns whose cells display values:
* `Property`: Defines the value to be displayed in this column's cells.
* `Format`: Optionally specifies a format string for the value. Using `Format` requires the `TProp` type to implement `IFormattable`.
* `Sortable`: Indicates whether the data should be sortable by this column. The default value may vary according to the column type. For example, a `TemplateColumn<TGridItem>` is sortable by default if any `TemplateColumn<TGridItem>.SortBy` parameter is specified.
* `InitialSortDirection`: Indicates the sort direction if `IsDefaultSortColumn` is `true`.
* `IsDefaultSortColumn`: Indicates whether this column should be sorted by default.
* `PlaceholderTemplate`: If specified, virtualized grids use this template to render cells whose data hasn't been loaded.
* <xref:Microsoft.AspNetCore.Components.QuickGrid.QuickGrid%601.Items%2A>: A nullable `IQueryable<TGridItem>`, where `TGridItem` is the type of data represented by each row in the grid.
* <xref:Microsoft.AspNetCore.Components.QuickGrid.QuickGrid%601.ItemsProvider%2A>: A callback that supplies data for the grid.
* <xref:Microsoft.AspNetCore.Components.QuickGrid.QuickGrid%601.Class%2A>: An optional CSS class name. If provided, the class name is included in the `class` attribute of the rendered table.
* <xref:Microsoft.AspNetCore.Components.QuickGrid.QuickGrid%601.Theme%2A>: A theme name (default value: `default`). This affects which styling rules match the table.
* <xref:Microsoft.AspNetCore.Components.QuickGrid.QuickGrid%601.Virtualize%2A>: If true, the grid is rendered with virtualization. This is normally used in conjunction with scrolling and causes the grid to fetch and render only the data around the current scroll viewport. This can greatly improve the performance when scrolling through large data sets. If you use <xref:Microsoft.AspNetCore.Components.QuickGrid.QuickGrid%601.Virtualize%2A>, you should supply a value for <xref:Microsoft.AspNetCore.Components.QuickGrid.QuickGrid%601.ItemSize%2A> and must ensure that every row renders with a constant height. Generally, it's preferable not to use <xref:Microsoft.AspNetCore.Components.QuickGrid.QuickGrid%601.Virtualize%2A> if the amount of data rendered is small or if you're using pagination.
* <xref:Microsoft.AspNetCore.Components.QuickGrid.QuickGrid%601.ItemSize%2A>: Only applicable when using <xref:Microsoft.AspNetCore.Components.QuickGrid.QuickGrid%601.Virtualize%2A>. <xref:Microsoft.AspNetCore.Components.QuickGrid.QuickGrid%601.ItemSize%2A> defines an expected height in pixels for each row, allowing the virtualization mechanism to fetch the correct number of items to match the display size and to ensure accurate scrolling.
* <xref:Microsoft.AspNetCore.Components.QuickGrid.QuickGrid%601.ItemKey%2A>: Optionally defines a value for `@key` on each rendered row. Typically, this is used to specify a unique identifier, such as a primary key value, for each data item. This allows the grid to preserve the association between row elements and data items based on their unique identifiers, even when the `TGridItem` instances are replaced by new copies (for example, after a new query against the underlying data store). If not set, the `@key` is the `TGridItem` instance.
* <xref:Microsoft.AspNetCore.Components.QuickGrid.QuickGrid%601.Pagination%2A>: Optionally links this `TGridItem` instance with a <xref:Microsoft.AspNetCore.Components.QuickGrid.PaginationState> model, causing the grid to fetch and render only the current page of data. This is normally used in conjunction with a <xref:Microsoft.AspNetCore.Components.QuickGrid.Paginator> component or some other UI logic that displays and updates the supplied <xref:Microsoft.AspNetCore.Components.QuickGrid.PaginationState> instance.
* In the `QuickGrid` child content (<xref:Microsoft.AspNetCore.Components.RenderFragment>), specify <xref:Microsoft.AspNetCore.Components.QuickGrid.PropertyColumn`2>s, which represent `TGridItem` columns whose cells display values:
* <xref:Microsoft.AspNetCore.Components.QuickGrid.PropertyColumn%602.Property%2A>: Defines the value to be displayed in this column's cells.
* <xref:Microsoft.AspNetCore.Components.QuickGrid.PropertyColumn%602.Format%2A>: Optionally specifies a format string for the value. Using <xref:Microsoft.AspNetCore.Components.QuickGrid.PropertyColumn%602.Format%2A> requires the `TProp` type to implement <xref:System.IFormattable>.
* <xref:Microsoft.AspNetCore.Components.QuickGrid.ColumnBase%601.Sortable%2A>: Indicates whether the data should be sortable by this column. The default value may vary according to the column type. For example, a <xref:Microsoft.AspNetCore.Components.QuickGrid.TemplateColumn%601> is sortable by default if any <xref:Microsoft.AspNetCore.Components.QuickGrid.TemplateColumn%601.SortBy%2A> parameter is specified.
* <xref:Microsoft.AspNetCore.Components.QuickGrid.ColumnBase%601.InitialSortDirection%2A>: Indicates the sort direction if <xref:Microsoft.AspNetCore.Components.QuickGrid.ColumnBase%601.IsDefaultSortColumn%2A> is `true`.
* <xref:Microsoft.AspNetCore.Components.QuickGrid.ColumnBase%601.IsDefaultSortColumn%2A>: Indicates whether this column should be sorted by default.
* <xref:Microsoft.AspNetCore.Components.QuickGrid.ColumnBase%601.PlaceholderTemplate%2A>: If specified, virtualized grids use this template to render cells whose data hasn't been loaded.

For example, add the following component to render a grid.

Expand All @@ -66,11 +64,11 @@ For an example that uses an <xref:System.Linq.IQueryable> with Entity Framework

To use Entity Framework (EF) Core as the data source:

* Add a ***prerelease*** package reference for the [`Microsoft.AspNetCore.Components.QuickGrid.EntityFrameworkAdapter`](https://www.nuget.org/packages/Microsoft.AspNetCore.Components.QuickGrid.EntityFrameworkAdapter) package. If using the .NET CLI to add the package reference, include the `--prerelease` option when you execute the [`dotnet add package` command](/dotnet/core/tools/dotnet-add-package).
* Add a package reference for the [`Microsoft.AspNetCore.Components.QuickGrid.EntityFrameworkAdapter`](https://www.nuget.org/packages/Microsoft.AspNetCore.Components.QuickGrid.EntityFrameworkAdapter) package.

[!INCLUDE[](~/includes/package-reference.md)]

* Call `AddQuickGridEntityFrameworkAdapter` on the service collection in the `Program` file to register an EF-aware implementation of `IAsyncQueryExecutor`:
* Call `AddQuickGridEntityFrameworkAdapter` on the service collection in the `Program` file to register an EF-aware <xref:Microsoft.AspNetCore.Components.QuickGrid.IAsyncQueryExecutor> implementation:

```csharp
builder.Services.AddQuickGridEntityFrameworkAdapter();
Expand Down
66 changes: 39 additions & 27 deletions aspnetcore/blazor/fundamentals/dependency-injection.md
Original file line number Diff line number Diff line change
Expand Up @@ -213,56 +213,70 @@ The DI system is based on the DI system in ASP.NET Core. For more information, s

## Request a service in a component

After services are added to the service collection, inject the services into the components using the [`@inject`](xref:mvc/views/razor#inject) Razor directive, which has two parameters:
:::moniker range=">= aspnetcore-9.0"

* Type: The type of the service to inject.
* Property: The name of the property receiving the injected app service. The property doesn't require manual creation. The compiler creates the property.
For injecting services into components, Blazor supports [constructor injection](#constructor-injection) and [property injection](#property-injection).

For more information, see <xref:mvc/views/dependency-injection>.
### Constructor injection

Use multiple [`@inject`](xref:mvc/views/razor#inject) statements to inject different services.
After services are added to the service collection, inject one or more services into components with constructor injection. The following example injects the `NavigationManager` service.

The following example shows how to use [`@inject`](xref:mvc/views/razor#inject). The service implementing `Services.IDataAccess` is injected into the component's property `DataRepository`. Note how the code is only using the `IDataAccess` abstraction:
`ConstructorInjection.razor`:

:::moniker range=">= aspnetcore-8.0"
```razor
@page "/constructor-injection"
:::code language="razor" source="~/../blazor-samples/8.0/BlazorSample_BlazorWebApp/Components/Pages/TheSunmakers.razor":::
<button @onclick="@(() => Navigation.NavigateTo("/counter"))">
Take me to the Counter component
</button>
```

:::moniker-end
`ConstructorInjection.razor.cs`:

:::moniker range=">= aspnetcore-7.0 < aspnetcore-8.0"
```csharp
using Microsoft.AspNetCore.Components;

:::code language="razor" source="~/../blazor-samples/7.0/BlazorSample_Server/Pages/dependency-injection/CustomerList.razor" highlight="2,19":::
public partial class ConstructorInjection(NavigationManager navigation)
{
protected NavigationManager Navigation { get; } = navigation;
}
```

:::moniker-end
### Property injection

:::moniker range=">= aspnetcore-6.0 < aspnetcore-7.0"
:::moniker-end

:::code language="razor" source="~/../blazor-samples/6.0/BlazorSample_Server/Pages/dependency-injection/CustomerList.razor" highlight="2,19":::
After services are added to the service collection, inject one or more services into components with the [`@inject`](xref:mvc/views/razor#inject) Razor directive, which has two parameters:

:::moniker-end
* Type: The type of the service to inject.
* Property: The name of the property receiving the injected app service. The property doesn't require manual creation. The compiler creates the property.

:::moniker range=">= aspnetcore-5.0 < aspnetcore-6.0"
For more information, see <xref:mvc/views/dependency-injection>.

:::code language="razor" source="~/../blazor-samples/5.0/BlazorSample_Server/Pages/dependency-injection/CustomerList.razor" highlight="2,19":::
Use multiple [`@inject`](xref:mvc/views/razor#inject) statements to inject different services.

:::moniker-end
The following example demonstrates shows how to use the [`@inject`](xref:mvc/views/razor#inject) directive. The service implementing `Services.NavigationManager` is injected into the component's property `Navigation`. Note how the code is only using the `NavigationManager` abstraction.

:::moniker range="< aspnetcore-5.0"
`PropertyInjection.razor`:

:::code language="razor" source="~/../blazor-samples/3.1/BlazorSample_Server/Pages/dependency-injection/CustomerList.razor" highlight="2,19":::
```razor
@page "/property-injection"
@inject NavigationManager Navigation
:::moniker-end
<button @onclick="@(() => Navigation.NavigateTo("/counter"))">
Take me to the Counter component
</button>
```

Internally, the generated property (`DataRepository`) uses the [`[Inject]` attribute](xref:Microsoft.AspNetCore.Components.InjectAttribute). Typically, this attribute isn't used directly. If a base class is required for components and injected properties are also required for the base class, manually add the [`[Inject]` attribute](xref:Microsoft.AspNetCore.Components.InjectAttribute):
Internally, the generated property (`Navigation`) uses the [`[Inject]` attribute](xref:Microsoft.AspNetCore.Components.InjectAttribute). Typically, this attribute isn't used directly. If a base class is required for components and injected properties are also required for the base class, manually add the [`[Inject]` attribute](xref:Microsoft.AspNetCore.Components.InjectAttribute):

```csharp
using Microsoft.AspNetCore.Components;

public class ComponentBase : IComponent
{
[Inject]
protected IDataAccess DataRepository { get; set; } = default!;
protected NavigationManager Navigation { get; set; } = default!;

...
}
Expand All @@ -271,13 +285,11 @@ public class ComponentBase : IComponent
> [!NOTE]
> Since injected services are expected to be available, the default literal with the null-forgiving operator (`default!`) is assigned in .NET 6 or later. For more information, see [Nullable reference types (NRTs) and .NET compiler null-state static analysis](xref:migration/50-to-60#nullable-reference-types-nrts-and-net-compiler-null-state-static-analysis).
In components derived from the base class, the [`@inject`](xref:mvc/views/razor#inject) directive isn't required. The <xref:Microsoft.AspNetCore.Components.InjectAttribute> of the base class is sufficient, and all the component requires is the [`@inherits`](xref:mvc/views/razor#inherits) directive:
In components derived from a base class, the [`@inject`](xref:mvc/views/razor#inject) directive isn't required. The <xref:Microsoft.AspNetCore.Components.InjectAttribute> of the base class is sufficient. The component only requires the [`@inherits`](xref:mvc/views/razor#inherits) directive. In the following example, any injected services of `CustomComponentBase` are available to the `Demo` component:

```razor
@page "/demo"
@inherits ComponentBase
<h1>Demo Component</h1>
@inherits CustomComponentBase
```

## Use DI in services
Expand Down
2 changes: 1 addition & 1 deletion aspnetcore/blazor/host-and-deploy/webassembly.md
Original file line number Diff line number Diff line change
Expand Up @@ -1243,7 +1243,7 @@ Placeholders:
>
> If you have any cause for concern that checksum validation isn't secure enough in your environment, consult your organization's security leadership for guidance.
>
> For more information, see [Understanding malware & other threats](/windows/security/threat-protection/intelligence/understanding-malware).
> For more information, see [Overview of threat protection by Microsoft Defender Antivirus](/microsoft-365/business-premium/m365bp-threats-detected-defender-av).
### Disable integrity checking for non-PWA apps
Expand Down
Loading

0 comments on commit 02c63b5

Please sign in to comment.