DetailsView¶
The DetailsView component emulates the ASP.NET Web Forms asp:DetailsView control. It displays a single record from a data source in a vertical table layout, with one row per field. It supports read-only, edit, and insert modes, paging between records, and auto-generated or explicitly defined fields.
Original Microsoft documentation: https://docs.microsoft.com/en-us/dotnet/api/system.web.ui.webcontrols.detailsview?view=netframework-4.8
Blazor Features Supported¶
- Single-record display in a two-column table (label + value per row)
AutoGenerateRows— automatically generates rows from the data item's public properties- Three display modes via
DetailsViewModeenum:ReadOnly,Edit,Insert DefaultMode— sets the initial modeModeChanging/ModeChangedeventsAutoGenerateEditButton,AutoGenerateDeleteButton,AutoGenerateInsertButton— command row buttons- CRUD events:
ItemCommand,ItemDeleting/ItemDeleted,ItemInserting/ItemInserted,ItemUpdating/ItemUpdated - Cancellable pre-operation events (
ItemDeleting,ItemInserting,ItemUpdating) AllowPagingwith numeric pager — navigate between items in the data sourcePageIndex/PageIndexChanging/PageIndexChangedeventsDataKeyNames— primary key field identificationHeaderText/HeaderTemplate,FooterText/FooterTemplateEmptyDataText/EmptyDataTemplate— displayed when data source is emptyPagerTemplate— custom pager UIFields— explicit field definitions (BoundField, TemplateField)GridLines,CellPadding,CellSpacing— table layout controlCssClass— CSS class on the outer tableCaption/CaptionAlign— renders a<caption>element for table accessibilityVisible— show/hide the entire control- Generic
ItemTypefor strongly typed data binding - Style sub-components (RowStyle, AlternatingRowStyle, HeaderStyle, FooterStyle, CommandRowStyle, EditRowStyle, InsertRowStyle, FieldHeaderStyle, EmptyDataRowStyle, PagerStyle)
- PagerSettings — configurable pager button modes, text, images, and position
Blazor Notes¶
- The component is generic:
DetailsView<ItemType>. You must specifyItemTypewhen using it. - Field definitions are added as child content inside a
<Fields>block. They register themselves with the parent via aCascadingValue. - When
AutoGenerateRows="true"(the default) and no explicit fields are defined, the component reflects overItemTypeto generate rows for each public readable property. - The pager displays one page number per item in the data source (each "page" is one record).
Web Forms Features NOT Supported¶
- DataSourceID — Blazor does not use server-side data source controls; bind data directly via
Items - Sorting —
AllowSortingis not implemented - CommandField / ButtonField columns — Use
AutoGenerateEditButton/AutoGenerateDeleteButton/AutoGenerateInsertButtonor custom templates - ViewState — Not needed; Blazor preserves component state natively
- Theming / SkinID — Not applicable to Blazor
Web Forms Declarative Syntax¶
<asp:DetailsView
AllowPaging="True|False"
AutoGenerateDeleteButton="True|False"
AutoGenerateEditButton="True|False"
AutoGenerateInsertButton="True|False"
AutoGenerateRows="True|False"
Caption="string"
CaptionAlign="NotSet|Top|Bottom|Left|Right"
CellPadding="integer"
CellSpacing="integer"
CssClass="string"
DataKeyNames="string"
DataSourceID="string"
DefaultMode="ReadOnly|Edit|Insert"
EmptyDataText="string"
GridLines="None|Horizontal|Vertical|Both"
HeaderText="string"
FooterText="string"
ID="string"
OnItemCommand="ItemCommand event handler"
OnItemDeleted="ItemDeleted event handler"
OnItemDeleting="ItemDeleting event handler"
OnItemInserted="ItemInserted event handler"
OnItemInserting="ItemInserting event handler"
OnItemUpdated="ItemUpdated event handler"
OnItemUpdating="ItemUpdating event handler"
OnModeChanged="ModeChanged event handler"
OnModeChanging="ModeChanging event handler"
OnPageIndexChanged="PageIndexChanged event handler"
OnPageIndexChanging="PageIndexChanging event handler"
PageIndex="integer"
Visible="True|False"
runat="server"
>
<AlternatingRowStyle />
<CommandRowStyle />
<EditRowStyle />
<EmptyDataRowStyle />
<FieldHeaderStyle />
<FooterStyle />
<HeaderStyle />
<InsertRowStyle />
<PagerSettings
Mode="NextPrevious|Numeric|NextPreviousFirstLast|NumericFirstLast"
FirstPageText="string"
LastPageText="string"
NextPageText="string"
PreviousPageText="string"
PageButtonCount="integer"
Position="Bottom|Top|TopAndBottom"
Visible="True|False"
/>
<PagerStyle />
<RowStyle />
<Fields>
<asp:BoundField DataField="string" HeaderText="string" ReadOnly="True|False" />
<asp:TemplateField HeaderText="string">
<ItemTemplate><!-- child controls --></ItemTemplate>
<EditItemTemplate><!-- child controls --></EditItemTemplate>
</asp:TemplateField>
</Fields>
<HeaderTemplate><!-- child controls --></HeaderTemplate>
<FooterTemplate><!-- child controls --></FooterTemplate>
<EmptyDataTemplate><!-- child controls --></EmptyDataTemplate>
<PagerTemplate><!-- child controls --></PagerTemplate>
</asp:DetailsView>
Blazor Syntax¶
<DetailsView ItemType="Product"
Items="@Products"
AutoGenerateRows="true"
AllowPaging="true"
AutoGenerateEditButton="true"
AutoGenerateDeleteButton="true"
DefaultMode="DetailsViewMode.ReadOnly"
HeaderText="Product Details"
EmptyDataText="No products found."
Caption="Product Record"
CaptionAlign="TableCaptionAlign.Top"
CssClass="details-grid"
GridLines="GridLines.Both"
ItemDeleting="HandleDeleting"
ItemUpdating="HandleUpdating"
ModeChanging="HandleModeChanging"
PageIndexChanging="HandlePageChanging">
<PagerSettings Mode="PagerButtons.NumericFirstLast"
FirstPageText="First"
LastPageText="Last"
Position="PagerPosition.Bottom" />
<RowStyle BackColor="#FFFFFF" />
<AlternatingRowStyle BackColor="#F7F7F7" />
<HeaderStyle BackColor="#336699" ForeColor="#FFFFFF" Font-Bold="true" />
<FooterStyle BackColor="#CCCCCC" />
<CommandRowStyle BackColor="#EEEEEE" />
<FieldHeaderStyle Font-Bold="true" />
<PagerStyle BackColor="#DDDDDD" HorizontalAlign="HorizontalAlign.Center" />
</DetailsView>
@code {
private List<Product> Products = new();
private void HandleDeleting(DetailsViewDeleteEventArgs e)
{
// e.RowIndex gives you the current page index
// Perform delete logic; set e.Cancel = true to abort
}
private void HandleUpdating(DetailsViewUpdateEventArgs e)
{
// Perform update logic; set e.Cancel = true to abort
}
private void HandleModeChanging(DetailsViewModeEventArgs e)
{
// e.NewMode tells you the target mode
// e.CancelingEdit tells you if this is a cancel operation
}
private void HandlePageChanging(PageChangedEventArgs e)
{
// e.NewPageIndex gives you the target page
}
}
With Explicit Fields¶
<DetailsView ItemType="Product"
Items="@Products"
AutoGenerateRows="false"
AllowPaging="true">
<Fields>
<BoundField DataField="Name" HeaderText="Product Name" />
<BoundField DataField="Price" HeaderText="Unit Price" />
<TemplateField HeaderText="Actions">
<ItemTemplate>
<a href="/products/@context.Id">View</a>
</ItemTemplate>
</TemplateField>
</Fields>
</DetailsView>
With Custom Templates¶
<DetailsView ItemType="Product"
Items="@Products"
AutoGenerateRows="true">
<HeaderTemplate>
<strong>Product Information</strong>
</HeaderTemplate>
<EmptyDataTemplate>
<p>No products available. <a href="/products/new">Add one</a>.</p>
</EmptyDataTemplate>
<FooterTemplate>
<em>Last updated: @DateTime.Now.ToShortDateString()</em>
</FooterTemplate>
</DetailsView>
HTML Output¶
The component renders a table with one row per field, matching the Web Forms DetailsView output:
<table cellspacing="0" rules="all" border="1"
style="border-collapse:collapse" class="details-grid">
<!-- Header Row -->
<tr>
<td colspan="2">Product Details</td>
</tr>
<!-- Field Rows (one per property or defined field) -->
<tr>
<td>Id</td>
<td>1</td>
</tr>
<tr>
<td>Name</td>
<td>Widget</td>
</tr>
<tr>
<td>Price</td>
<td>9.99</td>
</tr>
<!-- Command Row (when edit/delete/insert buttons enabled) -->
<tr>
<td colspan="2">
<a href="javascript:void(0);">Edit</a>
<a href="javascript:void(0);">Delete</a>
</td>
</tr>
<!-- Pager Row (when AllowPaging and multiple items) -->
<tr>
<td colspan="2">
<table>
<tr>
<td><span>1</span></td>
<td><a href="javascript:void(0);">2</a></td>
<td><a href="javascript:void(0);">3</a></td>
</tr>
</table>
</td>
</tr>
<!-- Footer Row -->
<tr>
<td colspan="2">Footer text here</td>
</tr>
</table>
In Edit or Insert mode, the command row changes to show Update/Cancel or Insert/Cancel links:
<!-- Edit mode command row -->
<tr>
<td colspan="2">
<a href="javascript:void(0);">Update</a>
<a href="javascript:void(0);">Cancel</a>
</td>
</tr>
Style Sub-Components¶
The DetailsView supports style sub-components that control the appearance of different row types. Each is specified as a child element:
| Style Component | Description |
|---|---|
RowStyle |
Styles normal data rows |
AlternatingRowStyle |
Styles alternating data rows |
HeaderStyle |
Styles the header row |
FooterStyle |
Styles the footer row |
CommandRowStyle |
Styles the command row (Edit/Delete/Insert buttons) |
EditRowStyle |
Styles rows in Edit mode |
InsertRowStyle |
Styles rows in Insert mode |
FieldHeaderStyle |
Styles the field label cells (left column) |
EmptyDataRowStyle |
Styles the empty data row |
PagerStyle |
Styles the pager row |
Each style component accepts standard style properties: BackColor, ForeColor, CssClass, Font-Bold, Font-Italic, Font-Size, HorizontalAlign, VerticalAlign, Width, Height, etc.
Caption Property¶
The Caption and CaptionAlign properties render a <caption> element inside the <table>, providing an accessible description of the table's purpose:
<DetailsView ItemType="Product" Items="@Products"
Caption="Product Details"
CaptionAlign="TableCaptionAlign.Top" />
| CaptionAlign Value | Effect |
|---|---|
NotSet |
Default browser positioning |
Top |
Caption above the table |
Bottom |
Caption below the table |
Left |
Caption text left-aligned |
Right |
Caption text right-aligned |
Migration Notes¶
- Remove
asp:prefix — Change<asp:DetailsView>to<DetailsView> - Remove
runat="server"— Not needed in Blazor - Add
ItemType— The Blazor component is generic; specifyItemType="YourClass" - Replace
DataSourceID— UseItems="@yourCollection"instead of binding to a server-side DataSource control - Field declarations — Remove
asp:prefix from<asp:BoundField>and<asp:TemplateField>; place them inside<Fields>block - Event signatures — Events use typed
EventArgsclasses (DetailsViewDeleteEventArgs,DetailsViewUpdateEventArgs, etc.) - Styles — Web Forms
<HeaderStyle>,<RowStyle>, etc. work as child elements in Blazor with the same property names (BackColor, ForeColor, Font-Bold, etc.) - PagerSettings — Configure via child
<PagerSettings>element instead of dash-separated attributes. See PagerSettings for details.
Before (Web Forms)¶
<asp:DetailsView ID="dvProduct"
DataSourceID="SqlDataSource1"
AutoGenerateRows="True"
AllowPaging="True"
AutoGenerateEditButton="True"
OnItemUpdating="dvProduct_ItemUpdating"
runat="server">
<HeaderStyle BackColor="#336699" ForeColor="White" />
</asp:DetailsView>
After (Blazor)¶
<DetailsView ItemType="Product"
Items="@Products"
AutoGenerateRows="true"
AllowPaging="true"
AutoGenerateEditButton="true"
CssClass="product-details"
ItemUpdating="HandleUpdating">
<HeaderStyle BackColor="#336699" ForeColor="#FFFFFF" />
</DetailsView>
@code {
private List<Product> Products = new();
protected override async Task OnInitializedAsync()
{
Products = await ProductService.GetAllAsync();
}
private void HandleUpdating(DetailsViewUpdateEventArgs e)
{
// Perform update
}
}
See Also¶
- FormView — Similar single-record view with full template control
- GridView — Multi-record tabular display with similar field types
- DataList — Repeating data display
- PagerSettings — Shared pager configuration