AstrolUI AstrolUI
Amarillo Naranja Rojo Verde Azul Morado Color propio
Modo claro
Grid

1. Demo AstrolGrid

Nota:
En este ejemplo se implementan confirmaciones, notificaciones y botones, por lo que se recomienda ver la documentación de los mismos.
Full name
Age
1
Juan Pérez
34,56
Widower
True
25
01/01/2022
2
María García
23,14
Married
False
32
15/03/2021
3
Pedro Rodríguez
36,32
Single
True
45
30/06/2020
4
Laura Fernández
56,09
Divorced
False
19
28/02/2022
5
Carlos Sánchez
12,05
Married
True
56
01/12/2019
de 4
@using Astrol.Component.Basic.Grid
@using Astrol.Component.Basic.Button
@using Astrol.Component.Basic.Confirm
@using Astrol.Entities.Basic.Static.Notification
@using Astrol.Entities.Basic.UI
@using Astrol.JSInterop.Base
@inject AstrolJSInterop jsI
 
<AstrolConfirm @ref="_conf" />
<AstrolGrid TItem="Client" PageSize="5" Data="dataList" @ref="_grid">
 <Columns>
 <Column Name="@nameof(Client.Id)" Title="Id" Width="55px" Sortable="true" Resizable="true">
 <span>@context.Id</span>
 </Column>
 <Column Name="@nameof(Client.FullName)" Title="Full name" Width="200px" Filtrable="true" Resizable="true" />
 <Column ClassHead="blue-head" ClassRow="blue-row" Name="@nameof(Client.Points)" Title="Points" Sortable="true" Filtrable="true" Resizable="true" />
 <Column Name="@nameof(Client.MaritalStatus)" Title="Marital status" Sortable="true" Filtrable="true" Resizable="true" />
 <Column Name="@nameof(Client.Sex)" Title="Sex" Width="80px" Sortable="true" Filtrable="true" Resizable="true" />
 <Column Name="@nameof(Client.Age)" Title="Age" Filtrable="true" Resizable="true" />
 <Column Name="@nameof(Client.RegistrationDate)" Title="Date" Format="dd/MM/yyyy" TypeOf="typeof(DateOnly)" Sortable="true" Filtrable="true" Resizable="true" />
 <Column Width="60px">
 <AstrolButton Icon="astrol-trash" Title="Delete" Style="AstrolStyle.Red" OnClick="() => DeleteItem(context)" />
 </Column>
 </Columns>
</AstrolGrid>
<style>
 /* !important: the grid header and cells use scoped css */
 .blue-head {
 background-color: rgb(from var(--color-base) r g b / 80%) !important;
 }
 .blue-row {
 background-color: rgb(from var(--color-base) r g b / 40%) !important;
 }
</style>
@code {
 private AstrolGrid<Client>? _grid;
 private AstrolConfirm? _conf;
 private List<Client> dataList = new List<Client> {
 new Client { Id = 1, Points= 34.56F, Name = "Juan", Surnames = "Pérez", Sex = true, MaritalStatus = MaritalStatus.Widower, Age = 25, RegistrationDate = new DateTime(2022, 1, 1) },
 new Client { Id = 2, Points= 23.14F, Name = "María", Surnames = "García", Sex = false, MaritalStatus = MaritalStatus.Married, Age = 32, RegistrationDate = new DateTime(2021, 3, 15) },
 new Client { Id = 3, Points= 36.32F, Name = "Pedro", Surnames = "Rodríguez", Sex = true, Age = 45, MaritalStatus = MaritalStatus.Single, RegistrationDate = new DateTime(2020, 6, 30) },
 new Client { Id = 4, Points= 56.09F , Name = "Laura", Surnames = "Fernández", Sex = false, Age = 19, MaritalStatus = MaritalStatus.Divorced,RegistrationDate = new DateTime(2022, 2, 28) },
 new Client { Id = 5, Points= 12.05F, Name = "Carlos", Surnames = "Sánchez", Sex = true, Age = 56,MaritalStatus = MaritalStatus.Married, RegistrationDate = new DateTime(2019, 12, 1) },
 new Client { Id = 6,Points= 15.26F, Name = "Ana", Surnames = "Gómez", Age = 29, Sex = false, RegistrationDate = new DateTime(2021, 7, 10) },
 new Client { Id = 7,Points= 14.34F , Name = "Pablo", Surnames = "Martínez", Sex = true, Age = 41, MaritalStatus = MaritalStatus.Married, RegistrationDate = new DateTime(2022, 4, 5) },
 new Client { Id = 8,Points= 5.2F, Name = "Lucía", Surnames = "Jiménez", Age = 22,Sex = false, RegistrationDate = new DateTime(2023, 1, 2) },
 new Client { Id = 9,Points= 88.53F, Name = "Javier", Surnames = "Hernández",Sex = true, Age = 37,MaritalStatus = MaritalStatus.Married, RegistrationDate = new DateTime(2022, 9, 15) },
 new Client { Id = 10,Points= 45.23F , Name = "Sofía", Surnames = "Ruiz",Sex = false, Age = 28, RegistrationDate = new DateTime(2023, 3, 20) },
 new Client { Id = 11,Points= 32.54F, Name = "Miguel", Surnames = "López",Sex = true, Age = 60, MaritalStatus = MaritalStatus.Other, RegistrationDate = new DateTime(2020, 5, 11) },
 new Client { Id = 12,Points= 14.52F, Name = "Carmen", Surnames = "González",Sex = false, Age = 31, RegistrationDate = new DateTime(2021, 11, 16) },
 new Client { Id = 13,Points= 78.8F, Name = "Antonio", Surnames = "Santos",Sex = true, Age = 48, RegistrationDate = new DateTime(2020, 3, 7) },
 new Client { Id = 14,Points= 65.456F, Name = "Isabel", Surnames = "Ortega",Sex = false, Age = 20,MaritalStatus = MaritalStatus.Other, RegistrationDate = new DateTime(2022, 7, 31) },
 new Client { Id = 15,Points= 56, Name = "David", Surnames = "Ramírez",Sex = true,Age = 43, RegistrationDate = new DateTime(2019, 10, 25) },
 new Client { Id = 16,Points= 34.01F, Name = "Raquel", Surnames = "Pardo",Sex = false, Age = 26,MaritalStatus = MaritalStatus.Other, RegistrationDate = new DateTime(2021, 2, 14) },
 };
 private async Task DeleteItem(Client item) {
 if (await _conf!.Confirmation("Are you sure?", "Do you want to delete the item?")) {
 dataList.Remove(item);
 await jsI.Notification("Item removed successfully.".NotificationSuccess("astrol-ok"));
 await _grid!.RefreshGrid();
 }
 }
 public class Client {
 public int Id { get; set; }
 public string? Name { get; set; }
 public bool Sex { get; set; }
 public string? Surnames { get; set; }
 public int Age { get; set; }
 public float Points { get; set; }
 public DateTime RegistrationDate { get; set; }
 public MaritalStatus MaritalStatus { get; set; }
 public string FullName => $"{Name} {Surnames}";
 }
 public enum MaritalStatus {
 Single,
 Married,
 Divorced,
 Widower,
 Other
 }
}

Parámetros que admite

  • TItem (objeto), tipo de las filas del grid.
  • Data (IEnumerable<TItem>), datos en memoria: el grid ordena, filtra y pagina en el cliente sin copiar ni modificar la lista. Si cambia el contenido sin cambiar la lista, llame a RefreshGrid() o cambie DataVersion.
  • DataVersion (object), cámbielo para forzar el refresco cuando cambia el contenido de Data sin cambiar la referencia ni el número de elementos. También funciona con ReadItems (vuelve a llamar al servidor).
  • ReadItems (EventCallback<GridResponse<TItem>>), lectura en servidor (ver más abajo). Si se asigna, no se usa Data.
  • ShowLoad (bool), muestra la animación de cargando mientras se obtienen los datos (por defecto true).
  • IconLoad (string), ícono de carga (por defecto astrol-spin5 ).
  • Pageable (bool), paginado (por defecto true).
  • PageSize (int), elementos por página (por defecto 10).
  • PageSizeList (List<int>), opciones del selector de tamaño de página (por defecto { 5, 10, 20, 50, 100, int.MaxValue }; int.MaxValue es "Todos").
  • Selectable (bool), filas seleccionables con checkbox (por defecto false).
  • KeySelector (Func<TItem, object?>), clave única de cada fila: conserva la selección entre páginas y recargas y mejora el rendimiento al reordenar.
  • OnSelected (EventCallback<List<TItem>>), se invoca al cambiar la selección con la lista de filas seleccionadas.
  • Virtualize (bool), pinta solo las filas visibles; útil con páginas grandes o sin paginar. RowHeight (float, alto aproximado de fila, por defecto 41) y OverscanCount (int, por defecto 5).
  • Options (RenderFragment), zona superior para botones u opciones del grid.
  • Textos (string): NoSearchResultText, PagePaginationText, OfPaginationText, PageSizePaginationText, ItemPaginationText, AllPaginationText, SelectAllText, SelectRowText. Si no se indican, salen en el idioma de la aplicación (español o inglés). Los textos de los botones de navegación de la paginación salen siempre de AstrolText.
  • Métodos y propiedades: RefreshGrid(resetSelection = true) vuelve a leer los datos (por defecto vacía la selección, sin invocar OnSelected; use RefreshGrid(false) para conservarla), GridInfo (página, orden y filtros actuales) y CurrentPageItems (filas visibles).
  • Columns (RenderFragment), columnas del grid (<Column />). Dentro de una columna, context es la fila.
    • Name (string): propiedad a mostrar, ordenar y filtrar; admite rutas como "Cliente.Nombre". Es el valor que llega al servidor en ColumnSort / ColumnFilter.
    • Field (Expression): alternativa tipada a Name, p. ej. Field="x => x.Cliente.Nombre".
    • Title (string): texto de la cabecera.
    • Format (string): formato del valor cuando no hay contenido propio, p. ej. "dd/MM/yyyy" o "N2".
    • Width (string): ancho de la columna (por defecto auto).
    • Sortable (bool): ordenamiento al pulsar la cabecera (ascendente, descendente, sin orden); requiere Name o Field (por defecto false).
    • Filtrable (bool): filtro en la cabecera según el tipo de la propiedad: texto, número, fecha (DateOnly), fecha y hora (DateTime), hora (TimeOnly / TimeSpan), bool o enum; otros tipos no muestran filtro (por defecto false).
    • FilterPlaceholder (string): placeholder del filtro.
    • TypeOf (Type): tipo para elegir el filtro cuando no se puede deducir, p. ej. typeof(DateOnly).
    • DefaultValue (object): valor inicial del filtro.
    • Resizable (bool): permite cambiar el ancho arrastrando el borde derecho; el ancho se conserva al paginar u ordenar (por defecto false).
    • Id (string): identificador de la columna (opcional).
    • ClassHead / ClassRow (string): clases css de la cabecera y de las celdas.
    • ChildContent (RenderFragment<TItem>): contenido propio de cada celda; la fila es context.
  • ReadItems (EventCallback<GridResponse<TItem>>), carga desde su API. Recibe GridInfo y debe rellenar AstrolPaginatedResponse:
    • GridInfo: Page (int), PageSize (int), SortInfo (ColumnSort, SortDirection: None / Ascending / Descending) y FilterInfo (lista de ColumnFilter / ValueFilter).
    • AstrolPaginatedResponse<TItem>: TotalItems (int) y PageItems (IEnumerable<TItem>).
    • En el servidor puede usar query.SortList(gridInfo.SortInfo).Paginate(gridInfo): genera expresiones que EF Core traduce a SQL.
    • Los filtros no se aplican solos en el servidor: recorra FilterInfo y aplíquelos a su consulta (ValueFilter llega como texto). Las propiedades calculadas (p. ej. FullName) se ordenan en memoria pero EF Core no puede traducirlas a SQL.

2. Demo AstrolGrid seleccionable con opciones

Nota:
En este ejemplo se simula la carga de datos desde el servidor; las filas son seleccionables y se ha deshabilitado el filtrado por columnas.
KeySelector es necesario para conservar la selección entre páginas cuando los datos vienen del servidor (cada lectura devuelve objetos nuevos). Tras modificar los datos llame a RefreshGrid() mediante @ref (vacía la selección; RefreshGrid(false) la conserva). DataVersion es opcional: cámbielo para forzar el refresco desde parámetros.
Age
1
Juan Pérez
34,56
Widower
True
25
01/01/2022
2
María García
23,14
Married
False
32
15/03/2021
3
Pedro Rodríguez
36,32
Single
True
45
30/06/2020
4
Laura Fernández
56,09
Divorced
False
19
28/02/2022
5
Carlos Sánchez
12,05
Married
True
56
01/12/2019
de 4
OnSelected:
@using Astrol.Component.Basic.Grid
@using Astrol.Component.Basic.Button
@using Astrol.Entities.Basic.UI
@using Astrol.Entities.Basic.UI.Grid
@using Astrol.Entities.Basic.Response
@using Astrol.Entities.Basic.Static.Extensions
 
<AstrolGrid TItem="Client" PageSize="5" ReadItems="ReadItems" Selectable="true"
 KeySelector="x => x.Id" OnSelected="OnSelected" @ref="_gridServer">
 <Options>
 <AstrolButton Icon="astrol-trash" Style="AstrolStyle.Red" Text="Delete"
 OnClick="DeleteSelected" Status="@(_selected.Count > 0)" />
 </Options>
 <Columns>
 <Column Name="@nameof(Client.Id)" Title="Id" Width="55px" Sortable="true" />
 <Column Name="@nameof(Client.FullName)" Title="Full name" Sortable="true" />
 <Column Name="@nameof(Client.Points)" Title="Points" Sortable="true" />
 <Column Name="@nameof(Client.MaritalStatus)" Title="Marital status" Sortable="true" />
 <Column Name="@nameof(Client.Sex)" Title="Sex" Width="80px" Sortable="true" />
 <Column Name="@nameof(Client.Age)" Title="Age" />
 <Column Name="@nameof(Client.RegistrationDate)" Title="Date" Format="dd/MM/yyyy" Sortable="true" />
 </Columns>
</AstrolGrid>
@code {
 private AstrolGrid<Client>? _gridServer;
 private List<Client> _selected = new();
 // Simulates the database table (on a real server: an EF Core IQueryable).
 private List<Client> _db = new List<Client> { /* same data as example 1 */ };
 
 private async Task ReadItems(GridResponse<Client> request) {
 await Task.Delay(200); // simulated latency
 // Sorts, counts and pages (Astrol.Entities.Basic.Static.Extensions)
 request.AstrolPaginatedResponse = _db.AsQueryable().ToPaginatedResponse(request.GridInfo);
 
 // Async EF Core: same steps with SortList + Paginate
 // var query = dbContext.Clients.SortList(request.GridInfo.SortInfo);
 // request.AstrolPaginatedResponse = new() {
 // TotalItems = await query.CountAsync(),
 // PageItems = await query.Paginate(request.GridInfo).ToListAsync() };
 }
 private void OnSelected(List<Client> selected) => _selected = selected;
 private async Task DeleteSelected() {
 var ids = _selected.Select(x => x.Id).ToHashSet();
 _db.RemoveAll(x => ids.Contains(x.Id));
 _selected = new();
 await _gridServer!.RefreshGrid(); // reads again and clears the selection
 }
}
Markdown para IA © 2026 AstrolUI v10.0.13