LgListView
LgListView<TItem> présente une collection sous forme de liste personnalisable, généralement avec un rendu de type carte. Utilisez-le quand chaque élément doit afficher un contenu riche là où une grille tabulaire serait moins lisible : le composant apporte le même pipeline de données que LgGridView (chargement local ou distant [Queryable], tri, filtres, pagination) avec un rendu entièrement contrôlé par l'application. Comme la grille, la liste est rendue dans un LgFrame : son en-tête (titre, actions, repli) a le même aspect que celui de LgGridView.
<LgListView TItem="ProjectVm" Items="_projects" Title="#ProjectsTitle">
<ItemTemplate Context="project">
<LgCard CssClass="mb-2">
<LgLabel Text="@project.Item.Name" />
</LgCard>
</ItemTemplate>
</LgListView>
- Espace de noms :
Lagoon.UI.Components - Hérite de :
LgAriaComponentBase→LgComponentBase - Package NuGet :
Lagoon.UI
Utilisation
Démonstration
Essayez ce composant dans le showcase Lagoon (vue d'ensemble), puis fonctionnalité par fonctionnalité :
- Simple
- Cartes
- Tri
- Pagination
- Filtres
- Sélection
- Regroupement
- Glisser-déposer
- Virtualisation
- Persistance d'état
Liste simple avec modèle de carte
Fournissez Items et ItemTemplate pour contrôler le rendu de chaque élément : le template reçoit un ListViewItemContext<TItem> dont la propriété Item porte l'élément. Sans ItemTemplate, le composant affiche une carte par défaut (voir Carte par défaut). Quand la source contient zéro élément, un message « aucune donnée » est affiché (NoDataTitle / NoDataDescription) ; une erreur de chargement affiche DataErrorTitle avec un bouton de relance. L'en-tête de la liste n'est rendu que s'il a un contenu : un Title, des tris, des filtres, une Toolbar ou la sélection (SelectableRows) ; une liste intégrée dans un autre bloc (colonne, onglet, fenêtre) n'a ainsi pas d'en-tête vide.
<LgListView TItem="ProjectVm"
Items="_projects"
Title="#ProjectsTitle"
AriaLabel="#ProjectsListAriaLabel">
<ItemTemplate Context="project">
<LgCard CssClass="mb-2">
<LgLabel Text="@project.Item.Name" />
<LgLabel Text="@project.Item.StatusLabel" CssClass="ml-2" />
</LgCard>
</ItemTemplate>
</LgListView>
public partial class ProjectsPage : LgPage
{
// Contient les éléments affichés : au rendu suivant de la page, la liste est rechargée quand la
// référence ou le nombre d'éléments a changé (ou après un événement d'une ObservableCollection) ;
// pour toute autre mutation, ou hors d'un rendu de la page, appeler RefreshAsync().
private readonly List<ProjectVm> _projects = new()
{
new ProjectVm { Name = "Lagoon Portal", StatusLabel = "#ProjectStatusActive" },
new ProjectVm { Name = "Lagoon Mobile", StatusLabel = "#ProjectStatusPending" }
};
// Modèle minimal de la carte : il porte uniquement les données nécessaires au template.
private sealed class ProjectVm
{
public string Name { get; set; }
public string StatusLabel { get; set; }
}
}
En-tête : titre, actions et repli
La liste est un cadre (LgFrame) : Title, IconName, TitleContent et Kind habillent son en-tête comme celui d'un LgFrame, et Collapsable permet de la replier d'un clic sur l'en-tête (Collapsed liable en two-way, DefaultCollapsed pour l'état initial). Ne placez donc pas une LgListView dans un LgFrame : vous obtiendriez un cadre dans un cadre.
La barre d'actions de l'en-tête suit l'ordre de la grille : d'abord les boutons de Toolbar, puis les boutons intégrés — « Filtres » et « Effacer » (avec Filters, voir Filtres déclaratifs) et le menu de tri (avec SortOptions, voir Tri déclaratif). Ses boutons ont la taille des boutons de toolbar des cadres (App.BehaviorConfiguration.FrameToolbarButtonSize). Quand la liste est repliée, les boutons intégrés et la case « Tout sélectionner » sont masqués ; ceux de Toolbar restent visibles.
L'en-tête n'est rendu que s'il a un contenu : Title, IconName, TitleContent, un filtre déclaré dans Filters, un tri dans SortOptions, une Toolbar, la sélection (SelectableRows) ou Collapsable. Sans aucun d'eux, la liste s'affiche sans en-tête.
Comme dans le titre de LgGridView, deux compteurs du dernier chargement sont remplacés dans Title, y compris après traduction d'un titre #clé : {0} par le nombre total d'éléments (filtres appliqués) et {1} par le nombre d'éléments de la page affichée (tous les éléments sans AllowPaging). Un compteur inconnu s'affiche ... : avant le premier chargement, et pour {1} quand la page est vide ({0} vaut alors 0). Pendant un rechargement, les compteurs du chargement précédent restent affichés. Pour afficher les compteurs ailleurs que dans le titre, liez ListViewDataCounter (voir Pagination).
<!-- ProjectsCountTitle (Dico.xml) : fr="Projets ({0})" en="Projects ({0})" -->
<LgListView TItem="ProjectVm"
Items="_projects"
Title="#ProjectsCountTitle"
IconName="@IconNames.All.ListUl"
Collapsable="true"
@bind-Collapsed="_collapsed">
<Toolbar>
<LgToolbarButton Text="#AddProject" IconName="@IconNames.All.Plus" OnClick="AddProjectAsync" />
</Toolbar>
<ItemTemplate Context="project">
<LgCard CssClass="mb-2">
<LgLabel Text="@project.Item.Name" />
</LgCard>
</ItemTemplate>
</LgListView>
public partial class CollapsableProjectsPage : LgPage
{
private readonly List<ProjectVm> _projects = new();
// État replié lié en two-way : la page peut le lire ou le modifier (ex. replier la liste après une action).
private bool _collapsed;
// Ajoute un élément : le composant détecte le changement de nombre, recharge la liste et met à jour le titre.
private Task AddProjectAsync(ActionEventArgs args)
{
_projects.Add(new ProjectVm { Name = "Lagoon Back Office" });
return Task.CompletedTask;
}
private sealed class ProjectVm
{
public string Name { get; set; }
}
}
Carte par défaut (sans ItemTemplate)
Sans ItemTemplate, chaque élément est rendu dans une LgCard construite à partir de paramètres facultatifs :
BodyContent(RenderFragment<TItem>) : contenu du corps de la carte (div.card-body) ; à défaut,item.ToString()est affiché.ColorSelector(Func<TItem, string>) : couleur CSS de la bande de couleur (LgCardStripe) de l'élément.StripeCssClassSelector(Func<TItem, string>) : classes CSS de la bande, pour la colorer par une classe du thème (bg-dangerpar exemple) plutôt que par une couleur.StripeIconSelector(Func<TItem, string>) : nom de l'icône affichée dans la bande.StripeContent(RenderFragment<TItem>) : contenu rendu dans la bande de couleur (un compteur par exemple). La bande prend alors la largeur de son contenu (au minimum celle de la variante avec icône).CssClassSelector(Func<TItem, string>) : classes CSS ajoutées à la carte de l'élément.
La bande est rendue pour un élément dès que ColorSelector, StripeCssClassSelector ou StripeIconSelector retourne une valeur (ni null ni chaîne vide), ou quand StripeContent est renseigné : StripeContent donne donc une bande à tous les éléments. Sans couleur ni classe, la bande garde la couleur du thème, comme une LgCardStripe sans Color. Un élément sans aucun de ces quatre paramètres n'a pas de bande : son corps commence alors plus à gauche que celui des éléments qui en ont une.
La carte reçoit aussi le clic, l'élément actif, le lien, l'infobulle et la confirmation de la liste (voir Cartes cliquables et élément actif).
ItemTemplate reste prioritaire : quand il est renseigné, la carte par défaut n'est pas générée, mais ses éléments restent disponibles dans le template (voir Réutiliser la carte dans ItemTemplate).
<LgListView TItem="ProjectVm"
Items="_projects"
Title="#ProjectsTitle"
ColorSelector="@(p => p.IsClosed ? null : p.StatusColor)"
StripeIconSelector="@(p => p.IsLate ? IconNames.All.ExclamationCircleFill : null)"
CssClassSelector="@(p => p.IsLate ? "font-weight-bold" : null)">
<BodyContent Context="project">
<div class="d-flex">
<LgLabel Text="@project.Name" CssClass="mr-3" />
<LgLabel Text="@project.StatusLabel" CssClass="ml-auto" />
</div>
</BodyContent>
</LgListView>
public partial class ProjectCardsPage : LgPage
{
// Projets affichés : StatusColor (couleur CSS, ex. "#62AC87" ou "var(--bs-danger)") colore la bande,
// un projet clos (IsClosed) n'en a pas et un projet en retard (IsLate) est mis en gras et signalé
// par une icône dans la bande.
private readonly List<ProjectVm> _projects = new();
// Modèle de la carte : les sélecteurs et les fragments de la liste lisent ses propriétés.
private sealed class ProjectVm
{
public string Name { get; set; }
public string StatusLabel { get; set; }
public string StatusColor { get; set; }
public bool IsClosed { get; set; }
public bool IsLate { get; set; }
}
}
Cartes cliquables et élément actif
Les cartes deviennent cliquables (classe card-clickable, focus clavier) quand la liste reçoit une action :
OnItemClick(EventCallback<TItem>) : déclenché au clic sur une carte, avec l'élément cliqué.@bind-ActiveItem(ActiveItem/ActiveItemChanged) : l'élément actif reçoit la classeactive; un clic sur une carte rend son élément actif avant de déclencherOnItemClick. Un clic sur la carte déjà active la laisse active. L'élément actif est comparé comme la sélection, surKeyField(ou sur la propriétéIdd'une liste distante sansKeyField) : il reste actif après un rechargement des données (changement de page, liste distante). Sans binding (ActiveItemseul), l'élément actif est seulement affiché.LinkSelector(Func<TItem, LgPageLink>) : page ouverte par la carte. Un élément avec un lien navigue, sans déclencherOnItemClickni changer l'élément actif ; un élément pour lequel le sélecteur retournenullgarde le comportement de clic de la liste.
Deux sélecteurs complètent la carte de chaque élément : TooltipSelector (infobulle, au format HTML avec TooltipIsHtml="true") et ConfirmationMessageSelector (message de confirmation affiché avant l'action du clic : élément actif, OnItemClick ou lien ; aucune confirmation quand il retourne null). La sélection reste indépendante du clic : elle se fait par la case à cocher (SelectableRows) ou par ToggleSelectionAsync() depuis un template.
<div class="row">
<div class="col-8">
<LgListView TItem="ProjectVm"
Items="_projects"
Title="#ProjectsTitle"
KeyField="@nameof(ProjectVm.Id)"
@bind-ActiveItem="_activeProject"
OnItemClick="OnProjectClickAsync"
ColorSelector="@(p => p.StatusColor)"
TooltipSelector="@(p => p.OwnerName)"
ConfirmationMessageSelector="@(p => p.IsLocked ? "#ConfirmOpenLockedProject" : null)" />
</div>
<div class="col-4">
@if (_activeProject is not null)
{
<LgLabel Text="@_activeProject.Name" />
}
</div>
</div>
public partial class ProjectMasterDetailPage : LgPage
{
// Projets affichés : la liste les compare sur Id (KeyField) pour retrouver l'élément actif après un rechargement.
private readonly List<ProjectVm> _projects = new();
// Élément actif (binding two-way) : mis à jour par la liste au clic sur une carte, avant OnProjectClickAsync.
private ProjectVm _activeProject;
// Clic sur une carte : l'élément est déjà actif ; un projet verrouillé n'arrive ici qu'après confirmation.
private Task OnProjectClickAsync(ProjectVm project)
{
try
{
// Charger le détail du projet...
}
catch (Exception ex)
{
ShowException(ex);
}
return Task.CompletedTask;
}
// Modèle de la carte : Id identifie le projet, les autres propriétés alimentent la carte et ses sélecteurs.
private sealed class ProjectVm
{
public int Id { get; set; }
public string Name { get; set; }
public string OwnerName { get; set; }
public string StatusColor { get; set; }
public bool IsLocked { get; set; }
public override string ToString()
{
return Name;
}
}
}
Réutiliser la carte dans ItemTemplate (ListViewItemContext)
Le contexte d'ItemTemplate est un ListViewItemContext<TItem> : en plus de l'élément, il expose les éléments de la carte par défaut construits à partir des paramètres de la carte (BodyContent, StripeContent, les sélecteurs, OnItemClick, ActiveItem...). Le template peut ainsi reprendre la carte, sa bande de couleur et son corps en y ajoutant son propre contenu.
| Membre | Type | Description |
|---|---|---|
Item | TItem | Élément à rendre. |
Index | int | Position de l'élément (à partir de 0) parmi les éléments affichés, c'est-à-dire dans la page courante avec AllowPaging ; elle reste juste en rendu virtualisé. |
IsSelected | bool | Indique si l'élément est sélectionné (toujours false sans SelectableRows). |
IsActive | bool | Indique si l'élément est l'élément actif (ActiveItem). |
Color | string | Couleur retournée par ColorSelector (null sans sélecteur). |
CssClass | string | Classes CSS retournées par CssClassSelector (null sans sélecteur). RenderCard les applique ; sinon, le template les applique où il le souhaite. |
RenderCard(content) | RenderFragment | LgCard de l'élément autour d'un contenu libre : clic (OnItemClick, élément actif), lien, infobulle, confirmation, classe active et CssClass, comme la carte par défaut. Avec le glisser-déposer, la poignée (RenderDragHandle()) est rendue en premier dans la carte. |
RenderDragHandle() | RenderFragment | Poignée de glisser-déposer (bouton avec une icône de préhension) quand les éléments peuvent être déplacés (DragMode) ; null sinon. Déjà rendue par RenderCard : à appeler seulement dans un template qui n'utilise pas RenderCard (voir Glisser-déposer). |
RenderStripe() | RenderFragment | Bande de couleur (LgCardStripe) de la couleur Color, avec les classes de StripeCssClassSelector, l'icône de StripeIconSelector et StripeContent (couleur du thème sans couleur ni classe) ; ne rend rien quand l'élément n'a ni couleur, ni classe de bande, ni icône, et que StripeContent n'est pas renseigné. |
RenderBody() | RenderFragment | Corps de la carte : un div.card-body contenant BodyContent, ou item.ToString() à défaut. |
ActivateAsync() | Task | Rend l'élément actif (ActiveItemChanged est déclenché), sans déclencher OnItemClick ; sans effet quand il l'est déjà. |
ToggleSelectionAsync() | Task | Sélectionne l'élément, ou le désélectionne s'il l'est déjà, comme sa case à cocher (OnRowSelection est déclenché) ; sans effet sans SelectableRows. |
Le contexte s'affiche comme l'élément (@context rend item.ToString()).
RenderCard garde le comportement de la carte de la liste (clic, élément actif...) tout en laissant le template écrire son contenu :
<LgListView TItem="ProjectVm"
Items="_projects"
Title="#ProjectsTitle"
@bind-ActiveItem="_activeProject"
ColorSelector="@(p => p.StatusColor)">
<BodyContent Context="project">
<LgLabel Text="@project.Name" />
</BodyContent>
<ItemTemplate Context="card">
@card.RenderCard(
@<div class="d-flex w-100">
@card.RenderStripe()
@card.RenderBody()
<div class="card-body flex-grow-0">
<LgButton Text="#ArchiveProject" OnClick="@(() => ArchiveProjectAsync(card.Item))" />
</div>
</div>)
</ItemTemplate>
</LgListView>
Pour basculer la sélection au clic, le template écrit sa propre carte et appelle ToggleSelectionAsync() :
<LgListView TItem="ProjectVm"
Items="_projects"
Title="#ProjectsTitle"
SelectableRows="true"
ColorSelector="@(p => p.StatusColor)"
CssClassSelector="@(p => p.IsLate ? "font-weight-bold" : null)">
<BodyContent Context="project">
<LgLabel Text="@project.Name" />
</BodyContent>
<ItemTemplate Context="card">
<div class="card card-clickable @card.CssClass" @onclick="card.ToggleSelectionAsync">
@card.RenderStripe()
@card.RenderBody()
<div class="card-body">
<LgButton Text="#OpenProject"
OnClick="@(() => OpenProjectAsync(card.Item))" />
</div>
</div>
</ItemTemplate>
</LgListView>
public partial class ProjectCardTemplatePage : LgPage
{
// Projets affichés : StatusColor colore la bande et IsLate met la carte en gras (card.CssClass).
private readonly List<ProjectVm> _projects = new();
// Action propre au template : le bouton reçoit l'élément par le contexte (card.Item). LgButton stoppe la
// propagation du clic par défaut : seul un clic ailleurs sur la carte bascule sa sélection.
private Task OpenProjectAsync(ProjectVm project)
{
try
{
// Ouvrir le projet...
}
catch (Exception ex)
{
ShowException(ex);
}
return Task.CompletedTask;
}
// Modèle de la carte : les sélecteurs et le corps de la liste lisent ses propriétés.
private sealed class ProjectVm
{
public string Name { get; set; }
public string StatusColor { get; set; }
public bool IsLate { get; set; }
}
}
Disposition en grille
Par défaut, les éléments sont empilés sur toute la largeur. ItemMinWidth (longueur CSS, par exemple "18rem") les dispose en grille : autant de colonnes que la largeur de la liste le permet, chaque élément mesurant au moins ItemMinWidth (sauf si la liste est plus étroite), et les cartes d'une même rangée prennent la même hauteur. La grille s'applique à la carte par défaut comme à ItemTemplate ; elle est ignorée avec Virtualize, qui rend les éléments ligne par ligne.
<LgListView TItem="ProjectVm"
Items="_projects"
Title="#ProjectsTitle"
ItemMinWidth="16rem"
ColorSelector="@(p => p.StatusColor)">
<BodyContent Context="project">
<LgLabel Text="@project.Name" CssClass="font-weight-bold d-block" />
<LgLabel Text="@project.OwnerName" CssClass="d-block" />
</BodyContent>
</LgListView>
Tri déclaratif avec LgListViewSort
Chaque champ triable est déclaré par un composant LgListViewSort dans la section SortOptions ; le menu de tri de l'en-tête est généré à partir de ces déclarations. Son libellé indique le tri courant (« Trier par : Nom ») et une flèche son sens (↑ croissant, ↓ décroissant, comme les en-têtes de colonnes de LgGridView) ; il propose les déclarations puis les sens « Croissant » et « Décroissant », grisés tant qu'aucun tri n'est choisi. Le tri est appliqué par le pipeline de données (côté client en local, côté serveur en distant).
SortSelectorest une expression typéex => x.Membre, comme leSortSelectordes colonnes deLgGridView; le typeTItemest déduit de laLgListViewenglobante (il n'est pas à écrire). Une clé de type valeur est automatiquement « déboxée » pour rester traduisible en requête distante.- Clé du tri : le chemin du membre (
x => x.Owner.NamedonneOwner.Name). Elle identifie le tri dans l'état persisté (StateId) et dansOnSortChanged(Key). Pour une expression calculée (x => x.Quantity * x.UnitPrice, qui ne fonctionne qu'en local), renseignezKey: sans clé, une exception est levée. Deux déclarations ne peuvent pas avoir la même clé. - Libellé :
Textest facultatif ; à défaut, leNamede l'attribut[Display]du membre trié est utilis é, puis la clé. - Tri initial : la première déclaration marquée
IsDefault="true". Sans déclaration par défaut, la liste n'est pas triée au départ (les éléments gardent l'ordre de la source jusqu'au choix d'un tri).
<LgListView TItem="ProjectVm"
Items="_projects"
Title="#ProjectsTitle"
OnSortChanged="OnSortChangedAsync">
<SortOptions>
<LgListViewSort SortSelector="@(x => x.Name)" Text="#ProjectName" IsDefault="true" />
<LgListViewSort SortSelector="@(x => x.Status)" />
<LgListViewSort SortSelector="@(x => x.Name.Length)" Key="NameLength" Text="#ProjectNameLength" />
</SortOptions>
<ItemTemplate Context="project">
<LgCard CssClass="mb-2">
<LgLabel Text="@project.Item.Name" />
</LgCard>
</ItemTemplate>
</LgListView>
public partial class SortedProjectsPage : LgPage
{
private readonly List<ProjectVm> _projects = new()
{
new ProjectVm { Name = "Lagoon Portal", Status = ProjectStatus.Active },
new ProjectVm { Name = "Lagoon Archive", Status = ProjectStatus.Closed }
};
// Réagit au changement de tri : utile pour synchroniser un état externe (URL, analytics…).
private Task OnSortChangedAsync(ListViewSortEventArgs args)
{
// args.Key : clé du tri ("Name", "Status", "NameLength" ; null si aucun tri) ;
// args.SortDirection : Asc ou Desc (None si aucun tri).
// args.Sorts : le même tri sous la forme de la LgGridView (0 ou 1 couple (Key, SortDirection)).
return Task.CompletedTask;
}
private sealed class ProjectVm
{
public string Name { get; set; }
// Libellé du tri déclaré sans Text.
[Display(Name = "#ProjectStatus")]
public ProjectStatus Status { get; set; }
}
private enum ProjectStatus
{
Active,
Closed
}
}
Pagination
AllowPaging active le pager intégré, présenté comme celui de LgGridView : sélecteur de taille, boutons de pages et, avec DisplayInputPageSelector, champ « aller à la page », regroupés sur la droite. Comme dans la grille, le pager n'affiche pas le nombre d'éléments : placez {0} dans Title (voir En-tête) ou liez ListViewDataCounter. DefaultPageSize doit appartenir à PaginationSizeSelector (sinon la première valeur du sélecteur s'applique) ; la valeur 0 dans le sélecteur propose « Tout » (et peut être la taille initiale). Changer AllowPaging ou PaginationSizeSelector (une taille qui n'est plus proposée est remplacée par la première du sélecteur) recharge la liste à partir de la première page. CurrentPage est liable en two-way. Un changement de tri ou de filtre ramène automatiquement à la première page. Comme dans la grille, avec Items le résultat filtré et trié est calculé une fois puis réutilisé par les changements de page et de taille de page : il est recalculé quand les filtres, le tri, le regroupement ou la source changent (autre collection, autre nombre d'éléments, évènement d'une ObservableCollection), et par RefreshAsync(), à appeler après une modification d'éléments sur place. Comme pour LgGridView, PaginationButtonCount fixe le nombre de boutons de page, DisplayInputPageSelector ajoute un champ numérique « aller à la page » (validé par Entrée ; un numéro hors limites est ramené à la première ou à la dernière page), PagerOnTop place le pager au-dessus des éléments, et ListViewDataCounter (liable en two-way) expose après chaque chargement le nombre d'éléments affichés (ActiveRows), le nombre de pages (TotalPages) et le nombre total d'éléments (TotalRows) ; il n'est notifié que lorsqu'un compteur change.
<LgListView TItem="ProjectVm"
Items="_projects"
Title="#ProjectsTitle"
AllowPaging="true"
DefaultPageSize="20"
DisplayInputPageSelector="true"
@bind-CurrentPage="_currentPage"
@bind-ListViewDataCounter="_counter">
<ItemTemplate Context="project">
<LgCard CssClass="mb-2">
<LgLabel Text="@project.Item.Name" />
</LgCard>
</ItemTemplate>
</LgListView>
public partial class PagedProjectsPage : LgPage
{
// Page courante liée en two-way : permet par exemple de restaurer la page depuis l'URL.
private int _currentPage = 1;
// Compteurs mis à jour après chaque chargement (ex. afficher _counter?.TotalRows dans le titre).
private ListViewDataCounter _counter;
// Source locale paginée côté client par le pipeline de données.
private readonly List<ProjectVm> _projects = new();
private sealed class ProjectVm
{
public string Name { get; set; }
}
}
Filtres déclaratifs
La section Filters héberge des composants LgListViewFilter réellement rendus dans un panneau repliable au-dessus de la liste. Chaque filtre affiche la boîte de filtre de LgGridView correspondant au type de son FilterSelector (l'expression typée x => x.Membre déduit aussi le type de la valeur filtrée) :
| Type de la valeur | Boîte de filtre |
|---|---|
string | texte : sélection de valeurs ou condition (contient, commence par, finit par) |
bool / bool? | booléen |
| énumération (nullable ou non) | sélection de valeurs de l'énumération |
numérique (int, decimal, double…) | sélection de valeurs ou condition (égal, entre, supérieur…) |
DateTime / DateTimeOffset | date (sélection, périodes, conditions) |
TimeSpan | heure (conditions) |
| autre type | sélection de valeurs |
L'onglet « Sélection » propose les valeurs de la source filtrées par les autres filtres de la liste (comme les colonnes de la grille), ou les valeurs de Items quand elles sont déclarées. En mode distant, ces valeurs ne sont disponibles que pour un membre simple (x => x.Membre).
Comme pour le tri, la clé du filtre est le chemin du membre (ou Key, obligatoire pour une expression calculée) et le libellé vient de Text, à défaut du [Display] du membre, puis de la clé. Le bouton « Filtres » de l'en-tête affiche ou masque le panneau et indique le nombre de filtres actifs ; ce bouton et le panneau ne sont affichés que lorsque Filters contient au moins un LgListViewFilter (un fragment vide, ou dont tous les filtres sont exclus par un @if, les masque) ; quand le panneau est affiché, le bouton « Effacer » placé à côté vide tous les filtres (il est grisé tant qu'aucun filtre n'est actif), comme le fait la méthode ClearFiltersAsync par code. Les filtres actifs sont combinés et appliqués par le pipeline de données, côté client comme côté serveur.
Avec ShowFiltersSummary="true", les filtres actifs sont résumés sous le titre, comme avec le ShowFiltersSummary de LgGridView : les deux premiers sous la forme « Libellé : valeur » (la valeur telle que l'affiche la boîte de filtre, avec une infobulle), les suivants comptés dans un élément « +N » dont l'infobulle les liste. Le résumé n'est affiché que lorsque le panneau de filtres est masqué (ouvert, le panneau montre déjà les valeurs), et disparaît quand aucun filtre n'est actif. Il reprend l'apparence du résumé de la grille dans chaque thème.
La visibilité du panneau suit le même contrat que LgGridView : ShowFilters est liable en two-way (@bind-ShowFilters) et sa valeur initiale est conservée, sauf si DefaultShowFilters est renseigné, qui l'emporte alors au premier rendu. Contrairement à la grille, masquer le panneau conserve les valeurs des filtres (ils restent appliqués et comptés sur le bouton « Filtres »).
Les filtres sont disposés en grille sur toute la largeur (sur une colonne dans les tiroirs) ; au-dessus des éléments, ils sont regroupés dans un bandeau teinté. Chaque boîte se présente comme une liste déroulante (chevron), « (aucun filtre) » en grisé ; un filtre qui a une valeur est mis en évidence (libellé et bordure de la couleur d'accent du thème) et porte une croix qui ne vide que ce filtre (rechargement et OnFilterChanged, comme une saisie). Les couleurs et dimensions sont des variables SCSS du thème ($list-view-filter-*, $list-view-filters-bg…).
FiltersPosition choisit où s'affiche le panneau (voir ListViewFiltersPosition) :
Top(par défaut) : au-dessus des éléments, dans la liste ; le bouton « Effacer » est dans la barre d'actions.Popup: dans une fenêtre modale centrée, avec l'aspect et le fond grisé d'uneLgModal;Left/Right: dans un tiroir pleine hauteur qui glisse depuis le bord gauche ou droit de l'écran, par-dessus la page, les filtres empilés sur une colonne.
En popup et en tiroir, le bouton « Filtres » ouvre la fenêtre, qui porte le titre « Filtres », ses boutons « Effacer » et « Fermer » et une croix de fermeture ; elle se ferme aussi avec Échap ou par un clic en dehors. Les boîtes de filtre s'y ouvrent normalement au-dessus de la fenêtre. Fermée, la fenêtre est seulement masquée : les filtres gardent leurs valeurs et restent appliqués (affichés par le résumé avec ShowFiltersSummary), et changer FiltersPosition à la volée conserve aussi les valeurs. Une fenêtre ouverte n'est pas rouverte par l'état persisté (StateId) au prochain affichage.
<LgListView TItem="ProjectVm"
Items="_projects"
Title="#ProjectsTitle"
FiltersPosition="ListViewFiltersPosition.Right"
ShowFiltersSummary="true">
<Filters>
<LgListViewFilter FilterSelector="@(x => x.Name)" Text="#ProjectName" />
<LgListViewFilter FilterSelector="@(x => x.Owner)" Text="#ProjectOwner" />
</Filters>
<ItemTemplate Context="project">
<LgCard CssClass="mb-2">
<LgLabel Text="@project.Item.Name" />
</LgCard>
</ItemTemplate>
</LgListView>
OnFilterChanged reçoit un ListViewFilterChangedEventArgs dont Filters contient les filtres actifs indexés par clé, et HasFilters() indique s'il en reste au moins un, comme GridViewFilterChangedEventArgs. L'événement n'est déclenché que lorsque l'ensemble des filtres actifs change (valider le même filtre ou vider des filtres déjà vides ne le déclenche pas), y compris quand des valeurs sont restaurées depuis StateId.
<LgListView TItem="ProjectVm"
Items="_projects"
Title="#ProjectsTitle"
@bind-ShowFilters="_showFilters"
ShowFiltersSummary="true"
OnFilterChanged="OnFilterChangedAsync">
<Filters>
<LgListViewFilter FilterSelector="@(x => x.Name)" Text="#ProjectName" />
<LgListViewFilter FilterSelector="@(x => x.Owner)" Text="#ProjectOwner" Items="_owners" />
<LgListViewFilter FilterSelector="@(x => x.Status)" />
<LgListViewFilter FilterSelector="@(x => x.DueDate)" Text="#ProjectDueDate" />
</Filters>
<ItemTemplate Context="project">
<LgCard CssClass="mb-2">
<LgLabel Text="@project.Item.Name" />
</LgCard>
</ItemTemplate>
</LgListView>
public partial class FilteredProjectsPage : LgPage
{
private readonly List<ProjectVm> _projects = new();
// Valeurs proposées par le filtre des responsables, au lieu des valeurs de la source.
private readonly string[] _owners = { "Anne Birney", "John Valdez" };
// Visibilité du panneau de filtres, liée en two-way (affiché au premier rendu).
private bool _showFilters = true;
// Réagit au changement des filtres actifs : args.Filters les indexe par clé ("Name", "Status"…),
// args.HasFilters() vaut false quand tous les filtres sont vidés.
private Task OnFilterChangedAsync(ListViewFilterChangedEventArgs args)
{
return Task.CompletedTask;
}
private sealed class ProjectVm
{
public string Name { get; set; }
public string Owner { get; set; }
// Libellé du filtre déclaré sans Text.
[Display(Name = "#ProjectStatus")]
public ProjectStatus Status { get; set; }
public DateTime DueDate { get; set; }
}
private enum ProjectStatus
{
Active,
Closed
}
}
Sélection avec barre d'actions
Comme pour LgGridView, SelectableRows="true" active les cases de sélection ; Selection reçoit la collection des éléments sélectionnés (une collection est créée si elle est omise). KeyField désigne la propriété qui identifie un élément : la sélection compare alors les éléments sur cette clé et survit aux rechargements (changement de page en mode distant notamment). Sans KeyField, une liste distante (ControllerUri) utilise la propriété Id du modèle quand il en a une, même si le modèle redéfinit l'égalité (Id doit alors identifier l'élément de façon unique) ; sinon, et pour une liste locale, l'égalité du type (Equals / IEquatable<T>) est utilisée. La clé suit un changement de KeyField ou de la source de données (locale ou distante).
La case « Tout sélectionner » est placée dans l'en-tête, devant le titre, dans la colonne des cases des éléments. Elle est cochée quand tous les éléments chargés sont sélectionnés, indéterminée quand une partie seulement l'est. Un clic sur la case cochée désélectionne tout ; sinon il sélectionne les éléments chargés, sans dupliquer ceux déjà sélectionnés. Elle est grisée tant que la liste ne contient aucun élément, et masquée quand la liste est repliée. Toolbar est affichée dans l'en-tête, tandis que ToolbarSelection alimente le panneau d'action visible dès qu'au moins un élément est sélectionné ; comme dans la grille, il s'affiche entre les éléments et le pager du bas.
<LgListView TItem="ProjectVm"
Items="_projects"
SelectableRows="true"
Selection="_selectedProjects"
KeyField="@nameof(ProjectVm.Id)"
OnRowSelection="OnRowSelectionAsync"
Title="#ProjectsTitle">
<Toolbar>
<LgToolbarButton Text="#AddProject" IconName="@IconNames.All.Plus" OnClick="AddProjectAsync" />
</Toolbar>
<ToolbarSelection>
<LgToolbarGroup Kind="ToolbarGroupKind.Primary">
<LgToolbarButton Text="#ArchiveSelection"
IconName="@IconNames.All.Archive"
OnClick="ArchiveSelectedAsync" />
</LgToolbarGroup>
</ToolbarSelection>
<ItemTemplate Context="project">
<LgCard CssClass="mb-2">
<LgLabel Text="@project.Item.Name" />
</LgCard>
</ItemTemplate>
</LgListView>
public partial class SelectableProjectsPage : LgPage
{
// Source principale de la liste : les actions peuvent y ajouter, retirer ou modifier des éléments.
private readonly List<ProjectVm> _projects = new()
{
new ProjectVm { Id = 1, Name = "Lagoon Portal" },
new ProjectVm { Id = 2, Name = "Lagoon Mobile" }
};
// Stocke les éléments cochés : la référence doit rester stable pour que le composant la mette à jour.
private readonly List<ProjectVm> _selectedProjects = new();
// Réagit à chaque changement de sélection : args.SelectAction distingue la sélection
// unitaire du « tout sélectionner » / « tout désélectionner ».
private Task OnRowSelectionAsync(ListViewSelectionEventArgs<ProjectVm> args)
{
return Task.CompletedTask;
}
// Ajoute un élément : le composant détecte le changement de nombre et recharge la liste.
private Task AddProjectAsync(ActionEventArgs args)
{
_projects.Add(new ProjectVm { Id = _projects.Count + 1, Name = "Lagoon Back Office" });
return Task.CompletedTask;
}
// Traite la sélection courante : vider la liste évite de conserver des éléments déjà archivés.
private Task ArchiveSelectedAsync(ActionEventArgs args)
{
_selectedProjects.Clear();
ShowSuccess("#ProjectsArchived");
return Task.CompletedTask;
}
// Modèle identifiable : la propriété Id sert de clé de sélection via KeyField.
private sealed class ProjectVm
{
public int Id { get; set; }
public string Name { get; set; }
}
}
Regroupement
GroupSelector (Expression<Func<TItem, object>>, par exemple x => x.Status) regroupe les éléments affichés sous un en-tête de groupe. La liste trie d'abord par groupe, puis par le tri choisi dans SortOptions : les éléments d'un groupe restent consécutifs, y compris en mode distant (ControllerUri), où ce tri est envoyé au serveur. Les groupes sont triés par GroupOrderSelector quand il est renseigné (le rang d'un statut regroupé par libellé, par exemple), puis par clé, dans l'ordre croissant. Comme pour SortSelector, une expression calculée ne fonctionne qu'en local.
- En-tête par défaut : la clé du groupe (le nom d'affichage
[Display]d'une valeur d'énumération, « (Vide) » pour une clénull) et le nombre d'éléments du groupe.GroupHeaderContentremplace ce contenu ;GroupColorSelector(Func<TItem, string>, appelé avec le premier élément du groupe) ajoute une bande de couleur à l'en-tête. - Repli : un clic sur l'en-tête (ou sur son bouton, au clavier) replie ou déplie le groupe. Comme sur une
LgGridViewgroupée, l'en-tête de la liste porte deux boutons « Déplier les groupes » et « Replier les groupes » (aussi accessibles parExpandAllGroups()/CollapseAllGroups()), qui s'appliquent à tous les groupes, y compris ceux repliés ou dépliés un par un ; ces boutons font afficher l'en-tête de la liste même sans titre.DefaultGroupCollapsed="true"replie tous les groupes au départ.GroupCollapsable="false"empêche de replier les groupes (par exemple dans un éditeur court où tout doit rester visible) : l'en-tête n'a plus de bouton de repli et n'est plus cliquable, les deux boutons de la liste ne sont pas affichés et les groupes restent dépliés. Les groupes repliés sont mémorisés par clé tant que la liste est affichée (changement de page, de tri ou rechargement compris) et, avecStateId, persistés pour le prochain affichage (voir Persistance d'état). - Sélection : avec
SelectableRows, l'en-tête porte une case à cocher qui sélectionne les éléments affichés du groupe, ou les désélectionne quand ils le sont tous (OnRowSelectionavecSelectGroup/UnselectGroup). Elle est cochée quand tout le groupe est sélectionné et marquée comme partielle quand une partie seulement l'est. - Pagination et virtualisation : les groupes sont calculés sur les éléments affichés, c'est-à-dire ceux de la page courante avec
AllowPaging; un groupe coupé par la pagination reprend en tête de la page suivante. AvecVirtualize, les en-têtes de groupe sont des lignes virtualisées comme les éléments. AvecItemMinWidth, chaque groupe a sa propre grille. - Présentation : l'en-tête est un bandeau arrondi, avec le nom du groupe en gras et le nombre d'éléments dans une pastille. Avec
GroupColorSelector, le bandeau est teinté de la couleur du groupe et le nom en reprend la teinte foncée ; la couleur est aussi exposée en variable CSS--list-view-group-colorsur l'en-tête, pour vos propres styles. L'en-tête reste collé en haut de la zone qui défile (la page, ou la liste quand elle a une hauteur) tant qu'on parcourt les éléments de son groupe — sauf en virtualisation, où un en-tête qui sort de la zone visible n'est plus rendu. Les éléments d'un groupe sont en retrait sous son en-tête : seul leur contenu est décalé, les cases à cocher restant alignées sur celle de l'en-tête (en disposition grille, c'est toute la grille du groupe). Variables SCSS :$list-view-group-header-tint,$list-view-group-text-shade,$list-view-group-header-radius,$list-view-group-spacing(espace supplémentaire entre deux groupes, nul par défaut),$list-view-group-indent(retrait des éléments,1.5rempar défaut).
GroupHeaderContent reçoit un ListViewGroupContext<TItem> :
| Membre | Type | Description |
|---|---|---|
Key | object | Clé du groupe retournée par GroupSelector. |
Text | string | Texte affiché de la clé (nom d'affichage d'une énumération, « (Vide) » pour null, ToString() sinon) ; le contexte s'affiche comme ce texte. |
Items | IReadOnlyList<TItem> | Éléments affichés du groupe (ceux de la page courante avec AllowPaging). |
Count | int | Nombre d'éléments affichés du groupe. |
Color | string | Couleur retournée par GroupColorSelector pour le premier élément du groupe (null sans sélecteur). |
IsCollapsed | bool | Indique si le groupe est replié. |
<LgListView TItem="ProjectVm"
Items="_projects"
Title="#ProjectsTitle"
SelectableRows="true"
KeyField="@nameof(ProjectVm.Id)"
GroupSelector="@(p => p.StatusLabel)"
GroupOrderSelector="@(p => p.StatusRank)"
GroupColorSelector="@(p => p.StatusColor)"
ColorSelector="@(p => p.StatusColor)">
<SortOptions>
<LgListViewSort SortSelector="@(x => x.Name)" Text="#ProjectName" IsDefault="true" />
</SortOptions>
<GroupHeaderContent Context="group">
<div class="d-flex">
<LgLabel Text="@group.Text" CssClass="mr-3" />
<LgLabel Text="@("ProjectCount".Translate(group.Count))" CssClass="ml-auto" />
</div>
</GroupHeaderContent>
<BodyContent Context="project">
<LgLabel Text="@project.Name" />
</BodyContent>
</LgListView>
public partial class GroupedProjectsPage : LgPage
{
// Projets affichés : regroupés par libellé de statut, les groupes suivant le rang du statut (StatusRank)
// et les projets d'un groupe le tri par nom.
private readonly List<ProjectVm> _projects = new();
// Modèle de la carte : StatusLabel est la clé de groupe, StatusRank l'ordre des groupes et StatusColor la couleur
// de la bande des cartes et de l'en-tête de groupe.
private sealed class ProjectVm
{
public int Id { get; set; }
public string Name { get; set; }
public string StatusLabel { get; set; }
public int StatusRank { get; set; }
public string StatusColor { get; set; }
}
}
Glisser-déposer
DragMode (drapeaux ListViewDragMode) active le glisser-déposer des éléments : Reorder pour réordonner la liste, DragOut / DropIn pour échanger des éléments avec les autres listes du même DragGroup (et de même type TItem), Copy pour copier au lieu de déplacer. Les éléments se déplacent par une poignée affichée à gauche de leur carte, avant la bande de couleur, à la souris, au toucher ou au clavier ; sur un écran tactile, un appui long (environ une demi-seconde, sans bouger le doigt) n'importe où sur la carte démarre aussi le glisser, hors des champs, liens et boutons de la carte : un appui bref reste un clic et un glissement rapide fait défiler la page. Avec DragFromItem="true", la souris (ou le stylet) déplace aussi l'élément depuis n'importe quel point de sa carte, avec les mêmes exclusions (champs, liens, boutons, éléments de rôle button) : un clic sans déplacement reste un clic, et le texte de la carte n'est plus sélectionnable. La poignée reste affichée pour le clavier. Pendant le survol, une ligne d'insertion indique l'emplacement de dépôt (verticale entre deux cartes d'une grille) ; une liste qui ne choisit pas la position (sans Reorder, triée ou vide) est surlignée en entier et reçoit l'élément à la fin. Aucune dépendance n'est ajoutée : le moteur JavaScript du composant utilise les Pointer Events.
<LgListView TItem="ProjectVm" Items="_projects" DragMode="ListViewDragMode.Reorder"
OnItemDropped="SaveOrderAsync">
<BodyContent Context="project">
<LgLabel Text="@project.Name" />
</BodyContent>
</LgListView>
L'acceptation d'un élément se décide à trois niveaux, qui se combinent :
- Modes et groupe, évalués dans le navigateur sans aller-retour : la liste source doit avoir
DragOut, la cibleDropIn, et les deux le mêmeDragGroup; à l'intérieur d'une liste,Reorderest nécessaire, et un tri actif l'annule (le tri décide de l'ordre). CanDropde la liste cible, appelé pendant le survol pour chaque position (le résultat est mémorisé pendant le glisser) avec unListViewDropContext<TItem>: une position refusée n'affiche pas de ligne, la carte glissée est encadrée en rouge et le curseur devient « interdit ».OnItemDropde la liste cible, au relâchement, avant la mise à jour :Cancel = truerefuse le dépôt (l'élément revient à sa place), ce qui permet une vérification asynchrone (appel serveur, confirmation).
<LgListView TItem="ProjectVm" Items="_backlog" DragMode="ListViewDragMode.All" DragGroup="sprint" />
<LgListView TItem="ProjectVm" Items="_sprint" DragMode="ListViewDragMode.All" DragGroup="sprint"
CanDrop="@(c => c.IsSameList || _sprint.Count < 5)" OnItemDropped="StateHasChanged" />
Mise à jour des données. Sans Cancel ni Handled, la liste met à jour elle-même ses éléments locaux (Items modifiable) : retrait de la liste source lors d'un déplacement entre listes, insertion avant le nouvel élément suivant (IList<TItem> ; ajout en fin pour une autre ICollection<TItem>), avec en mode Copy la copie créée par ItemCopyFactory de la liste source (l'instance elle-même à défaut). Le gestionnaire de OnItemDrop qui met à jour les données lui-même renseigne Handled = true : la liste se contente alors de se recharger. Les éléments chargés par ControllerUri ne sont jamais modifiés : le gestionnaire met à jour la source distante puis appelle RefreshAsync(). Une liste qui ne peut pas modifier ses éléments (ControllerUri, tableau ou autre collection en lecture seule) n'accepte donc les éléments des autres listes qu'avec un gestionnaire OnItemDrop. OnItemDropped est ensuite déclenché, une fois l'élément en place (pour enregistrer le nouvel ordre, par exemple) ; il provoque aussi le rendu du parent.
// <LgListView ... DragMode="ListViewDragMode.DragOut | ListViewDragMode.Copy" DragGroup="templates" ItemCopyFactory="CopyProject" />
private ProjectVm CopyProject(ProjectVm template)
{
return new ProjectVm() { Id = ++_lastId, Name = template.Name };
}
Listes groupées. Avec GroupSelector, l'élément peut être déposé dans un autre groupe (ou dans un groupe replié, à sa fin) seulement si OnItemDrop est branché : c'est le gestionnaire qui change la propriété groupée de l'élément à partir de TargetGroupKey (IsGroupChanged indique un changement de groupe) ; la liste place ensuite l'élément à la position de dépôt.
// <LgListView ... DragMode="ListViewDragMode.Reorder" GroupSelector="@(p => p.Status)" OnItemDrop="OnStatusDropAsync" />
private async Task OnStatusDropAsync(ListViewDropEventArgs<ProjectVm> e)
{
if (!e.IsGroupChanged)
{
return;
}
ProjectStatus status = (ProjectStatus)e.TargetGroupKey;
if (!await ProjectService.CanChangeStatusAsync(e.Item, status))
{
e.Cancel = true;
return;
}
e.Item.Status = status;
}
Template personnalisé. RenderCard rend la poignée dans la carte ; un ItemTemplate qui construit son propre rendu appelle RenderDragHandle() à l'endroit voulu (à la souris, le glisser ne démarre que depuis la poignée ; au toucher, l'appui long fonctionne sur tout l'élément) :
<ItemTemplate Context="item">
<div class="d-flex align-items-center">
@item.RenderDragHandle()
<span>@item.Item.Name</span>
</div>
</ItemTemplate>
Clavier. Depuis une poignée, Espace ou Entrée saisit l'élément, les flèches choisissent sa position (haut / bas d'une ligne de la grille, Début / Fin), Espace ou Entrée le dépose et Échap annule ; Ctrl + flèche le déplace directement d'une position. Les positions et le résultat sont annoncés aux lecteurs d'écran. Sans Reorder, le clavier ne peut rien déplacer : les poignées sont alors hors de l'ordre de tabulation et masquées aux technologies d'assistance. Le clavier réordonne l'élément dans sa liste (y compris d'un groupe à l'autre) ; le passage à une autre liste se fait à la souris ou au toucher (ou par les actions de l'application).
ListViewDropContext<TItem>
Position de dépôt passée à CanDrop ; ListViewDropEventArgs<TItem>, reçu par OnItemDrop et OnItemDropped, en hérite et ajoute Cancel et Handled.
| Membre | Type | Description |
|---|---|---|
Item | TItem | Élément glissé. |
Source / Target | LgListView<TItem> | Liste d'origine de l'élément / liste qui le reçoit. |
SourceIndex | int | Position de l'élément parmi les éléments affichés de la liste source. |
TargetIndex | int | Position d'insertion parmi les éléments affichés de la liste cible, avant le déplacement (dans la même liste, SourceIndex et SourceIndex + 1 désignent la place actuelle). |
PreviousItem / NextItem | TItem | Éléments affichés juste avant / après la position d'insertion (l'élément glissé exclu, dans le groupe cible) ; valeur par défaut en début / fin. |
SourceGroupKey / TargetGroupKey | object | Clé de groupe de l'élément dans la liste source / du groupe qui le reçoit (null sans regroupement). |
IsSameList | bool | L'élément est déplacé dans sa propre liste. |
IsGroupChanged | bool | L'élément est déposé dans un autre groupe que le sien. |
IsCopy | bool | L'élément est copié (Copy sur la liste source). |
Cancel | bool | (ListViewDropEventArgs) Refuse le dépôt : l'élément revient à sa place. |
Handled | bool | (ListViewDropEventArgs) Le gestionnaire a mis à jour les éléments : la liste se recharge seulement. |
CanDrop est appelé de façon synchrone depuis le navigateur, ce que permet Blazor WebAssembly ; sans appel synchrone possible, les positions sont acceptées au survol et vérifiées au relâchement.
Liste distante avec ControllerUri
Utilisez ControllerUri pour déléguer filtrage, tri et pagination au serveur : la liste envoie des requêtes $qd au contrôleur [Queryable], exactement comme LgGridView. Items est ignoré dans ce mode. Un changement de ControllerUri recharge la liste. ControllerQueryArg transmet un argument métier additionnel ; sa modification recharge la liste (comparaison par Equals, sur un clone si l'argument implémente ICloneable, comme pour LgGridView). Un nouveau chargement annule le chargement en cours, et seule la réponse du dernier chargement lancé est affichée. AllowCancellation permet à l'utilisateur d'annuler un chargement long puis de le relancer.
<LgListView TItem="OrderVm"
ControllerUri="api/Orders"
ControllerQueryArg="_queryArg"
AllowCancellation="true"
AllowPaging="true"
KeyField="@nameof(OrderVm.Id)"
Title="#OrdersTitle">
<ItemTemplate Context="order">
<LgCard CssClass="mb-2">
<LgLabel Text="@order.Item.Number" />
<LgLabel Text="@order.Item.CustomerName" CssClass="ml-2" />
</LgCard>
</ItemTemplate>
</LgListView>
public partial class OrdersRemotePage : LgPage
{
// Argument sérialisé dans les requêtes distantes pour appliquer un filtre métier côté serveur.
private readonly OrdersQueryArg _queryArg = new()
{
CustomerId = 42,
};
private sealed class OrdersQueryArg
{
public int CustomerId { get; set; }
}
}
Contrat des endpoints
- Route :
POST api/Orders/$qd - Body :
DataQueryRequest<OrdersQueryArg> - Retour : requête
IQueryable<OrderVm>décorée avec[Queryable]
[Route("api/[controller]")]
public class OrdersController : LgControllerBase
{
private readonly AppDbContext _db;
public OrdersController(AppDbContext db)
{
_db = db;
}
// Fournit la source distante : l'attribut Queryable applique les filtres, tris et pages envoyés par la liste.
[HttpPost("$qd")]
[Queryable]
public IActionResult GetOrders([FromBody] DataQueryRequest<OrdersQueryArg> args)
{
try
{
IQueryable<OrderVm> query = _db.Orders.Select(o => new OrderVm
{
Id = o.Id,
Number = o.Number,
CustomerName = o.Customer.Name,
CustomerId = o.CustomerId,
});
if (args.Arg?.CustomerId is int customerId)
{
query = query.Where(o => o.CustomerId == customerId);
}
return Ok(query);
}
catch (Exception ex)
{
return Problem(ex);
}
}
}
Hauteur et défilement dans la liste
Comme pour LgGridView, donnez une hauteur à la liste par son attribut style (height ou max-height) : les éléments défilent alors dans la liste, tandis que l'en-tête, les filtres affichés au-dessus des éléments, le panneau d'action et le pager restent visibles. Un changement de page, de taille de page, de tri ou de filtres ramène la zone des éléments en haut. Sans hauteur, la liste grandit avec ses éléments et défile avec la page.
<LgListView TItem="ProjectVm"
Items="_projects"
Title="#ProjectsTitle"
AllowPaging="true"
style="height: 600px">
<ItemTemplate Context="project">
<LgCard CssClass="mb-2">
<LgLabel Text="@project.Item.Name" />
</LgCard>
</ItemTemplate>
</LgListView>
Le défilement dans la liste n'est activé que si la hauteur est déclarée dans l'attribut style. Une hauteur donnée par une classe CSS (CssClass) n'est pas détectée : la liste prend cette hauteur, mais ses éléments n'y défilent pas.
Virtualisation
Pour les grandes listes, Virtualize="true" ne rend que les éléments visibles (composant Blazor Virtualize sur les données chargées). VirtualizeItemSize indique la hauteur attendue d'un élément en pixels. Comme pour LgGridView, la virtualisation se combine avec AllowPaging : ce sont alors les éléments de la page courante qui sont virtualisés (utile avec de grandes pages, ou la taille « Tout »). Le composant Virtualize défile avec le plus proche ancêtre défilant (overflow-y: auto ou scroll) : par défaut c'est le document. Pour faire défiler la liste elle-même, donnez-lui une hauteur par son attribut style (voir Hauteur et défilement dans la liste) : seuls les éléments visibles dans la liste sont alors rendus.
Un conteneur défilant dont la hauteur n'est pas contrainte grandit avec son contenu : Virtualize considère alors tous les éléments comme visibles et les rend tous, ce qui annule la virtualisation.
<LgListView TItem="ProjectVm"
Items="_projects"
Title="#ProjectsTitle"
Virtualize="true"
VirtualizeItemSize="72"
style="height: 600px">
<ItemTemplate Context="project">
<LgCard CssClass="mb-2">
<LgLabel Text="@project.Item.Name" />
</LgCard>
</ItemTemplate>
</LgListView>
Persistance d'état avec StateId
Quand StateId est renseigné, le tri (clé et sens), la taille de page, la visibilité du panneau de filtres (restaurée pour la position Top seulement), les filtres et les groupes repliés sont persistés dans le stockage local du navigateur et restaurés au prochain affichage (les filtres sont indexés par leur clé). Un état persisté illisible est ignoré (et tracé) sans bloquer le chargement ; une clé de tri persistée qui n'est plus déclarée dans SortOptions est ignorée au profit du tri initial, un filtre persisté dont le type ne correspond plus à la boîte de filtre (type du membre modifié) est ignoré, et les groupes repliés ne sont restaurés que pour le même regroupement (mêmes expressions GroupSelector et GroupOrderSelector) ; un regroupement modifié à la volée repart de DefaultGroupCollapsed. Quand l'état contient des valeurs de filtre, le premier chargement attend qu'elles soient restaurées : une seule requête, déjà filtrée, est émise. Chaque valeur persistée n'est appliquée qu'une fois : un composant de filtre recréé plus tard (dans un @if de Filters) garde la valeur courante. Retirer un composant de filtre actif recharge la liste sans ce filtre. Comme au chargement d'un profil de LgGridView, la restauration de filtres déclenche OnFilterChanged, et une visibilité du panneau restaurée différente de ShowFilters est notifiée par ShowFiltersChanged.
<LgListView TItem="ProjectVm"
Items="_projects"
StateId="projects-list"
AllowPaging="true">
<SortOptions>
<LgListViewSort SortSelector="@(x => x.Name)" Text="#ProjectName" IsDefault="true" />
</SortOptions>
<Filters>
<LgListViewFilter FilterSelector="@(x => x.Name)" Text="#ProjectName" />
</Filters>
<ItemTemplate Context="project">
<LgCard CssClass="mb-2">
<LgLabel Text="@project.Item.Name" />
</LgCard>
</ItemTemplate>
</LgListView>
Propriétés
Toutes les propriétés [Parameter] du composant, y compris celles héritées.
LgListView<TItem>
| Nom | Type | Défaut | Déclaré dans | Description |
|---|---|---|---|---|
ActiveItem | TItem | default | LgListView<TItem> | Élément actif (classe active sur sa carte), liable en two-way via ActiveItemChanged ; lié, il change au clic sur une carte. Comparé comme la sélection (voir KeyField). |
AdditionalAttributes | IReadOnlyDictionary<string, object> | null | LgListView<TItem> | Attributs supplémentaires appliqués au conteneur racine (le cadre). |
AllowCancellation | bool | false | LgListView<TItem> | Autorise l'utilisateur à annuler un chargement distant en cours (puis à le relancer). |
AllowPaging | bool | false | LgListView<TItem> | Active la pagination et le pager intégré. |
BodyContent | RenderFragment<TItem> | null | LgListView<TItem> | Contenu du corps de la carte par défaut (et de RenderBody() dans ItemTemplate) ; à défaut, item.ToString() est affiché. |
Collapsable | bool | false | LgListView<TItem> | Autorise le repli de la liste par un clic sur son en-tête. |
Collapsed | bool | false | LgListView<TItem> | État replié, liable en two-way via CollapsedChanged (n'a d'effet qu'avec Collapsable). |
ColorSelector | Func<TItem, string> | null | LgListView<TItem> | Couleur CSS de la bande de couleur de la carte (Color dans ItemTemplate) ; sans couleur, la bande garde la couleur du thème (elle est rendue quand ce sélecteur, StripeCssClassSelector ou StripeIconSelector retourne une valeur, ou avec StripeContent). |
ConfirmationMessageSelector | Func<TItem, string> | null | LgListView<TItem> | Message de confirmation affiché avant l'action du clic sur la carte d'un élément ; aucune confirmation quand il retourne null ou une chaîne vide. |
ControllerQueryArg | object | null | LgListView<TItem> | Argument métier additionnel sérialisé dans chaque requête distante. |
ControllerUri | string | null | LgListView<TItem> | URI du contrôleur [Queryable] fournissant les données ; active le mode distant (Items est alors ignoré). |
CssClass | string | null | LgListView<TItem> | Classes CSS ajoutées au conteneur racine (le cadre). |
CssClassSelector | Func<TItem, string> | null | LgListView<TItem> | Classes CSS ajoutées à la carte par défaut d'un élément (CssClass dans ItemTemplate, à appliquer par le template). |
CanDrop | Func<ListViewDropContext<TItem>, bool> | null | LgListView<TItem> | Indique si un élément glissé peut être déposé à une position de cette liste (liste cible), appelé pendant le survol (voir Glisser-déposer). |
CurrentPage | int | 0 | LgListView<TItem> | Index de la page courante (1 = première page), liable en two-way via CurrentPageChanged. |
DataErrorTitle | string | #lblListViewErrorTitle | LgListView<TItem> | Titre affiché quand le chargement des données échoue. |
DefaultCollapsed | bool? | null | LgListView<TItem> | État replié initial ; quand il est renseigné, il remplace la valeur initiale de Collapsed. |
DefaultGroupCollapsed | bool | false | LgListView<TItem> | Replie tous les groupes au départ (avec GroupSelector). |
DefaultPageSize | int? | null | LgListView<TItem> | Taille de page initiale (0 = « Tout ») ; doit appartenir à PaginationSizeSelector, sinon la première valeur du sélecteur s'applique. |
DefaultShowFilters | bool? | null | LgListView<TItem> | Visibilité initiale du panneau de filtres ; quand elle est renseignée, elle remplace la valeur initiale de ShowFilters. |
DisplayInputPageSelector | bool | false | LgListView<TItem> | Ajoute au pager un champ numérique « aller à la page » (validé par Entrée). |
DragFromItem | bool | false | LgListView<TItem> | La souris ou le stylet déplace un élément depuis n'importe quel point de sa carte, pas seulement depuis sa poignée (hors champs, liens et boutons) ; le toucher garde l'appui long, le clavier la poignée. Voir Glisser-déposer. |
DragGroup | string | null | LgListView<TItem> | Nom du groupe de listes qui échangent des éléments (DragOut / DropIn) ; sans groupe, les éléments ne peuvent être que réordonnés dans la liste. |
DragMode | ListViewDragMode | None | LgListView<TItem> | Capacités de glisser-déposer (drapeaux) : réordonnancement, sortie vers / entrée depuis les listes du même DragGroup, copie. |
Filters | RenderFragment | null | LgListView<TItem> | Déclarations de filtres (composants LgListViewFilter), rendues dans le panneau repliable. |
FiltersPosition | ListViewFiltersPosition | Top | LgListView<TItem> | Position du panneau de filtres : au-dessus des éléments, dans une fenêtre modale ou dans un tiroir à gauche ou à droite. |
GroupCollapsable | bool | true | LgListView<TItem> | Permet de replier et déplier les groupes (clic sur l'en-tête, boutons « Déplier les groupes » / « Replier les groupes »). À false, les groupes restent dépliés : pas de bouton de repli, en-tête non cliquable, DefaultGroupCollapsed et CollapseAllGroups() sans effet. |
GroupColorSelector | Func<TItem, string> | null | LgListView<TItem> | Couleur CSS de la bande de l'en-tête d'un groupe, appelée avec le premier élément du groupe ; pas de bande quand elle retourne null ou une chaîne vide. |
GroupHeaderContent | RenderFragment<ListViewGroupContext<TItem>> | null | LgListView<TItem> | Contenu de l'en-tête d'un groupe (voir Regroupement) ; à défaut, la clé du groupe et son nombre d'éléments. |
GroupOrderSelector | Expression<Func<TItem, object>> | null | LgListView<TItem> | Ordre des groupes (croissant) ; à défaut, les groupes sont triés par clé. Ignoré sans GroupSelector. |
GroupSelector | Expression<Func<TItem, object>> | null | LgListView<TItem> | Clé de groupe d'un élément x => x.Membre : regroupe les éléments affichés sous des en-têtes repliables, la liste triant d'abord par groupe (aussi côté serveur). |
IconName | string | null | LgListView<TItem> | Icône affichée devant le titre. |
ItemCopyFactory | Func<TItem, TItem> | null | LgListView<TItem> | Crée la copie d'un élément glissé de cette liste vers une autre en mode Copy ; à défaut, l'élément lui-même est inséré. |
ItemMinWidth | string | null | LgListView<TItem> | Largeur minimale d'un élément (longueur CSS, ex. "18rem") : dispose les éléments en grille. Ignorée avec Virtualize. |
ItemTemplate | RenderFragment<ListViewItemContext<TItem>> | null | LgListView<TItem> | Template de rendu d'un élément, prioritaire sur la carte par défaut ; son contexte expose l'élément (Item) et les éléments de la carte (voir ListViewItemContext). |
Items | ICollection<TItem> | null | LgListView<TItem> | Source locale des éléments. Ignorée quand ControllerUri est renseigné. Le résultat filtré et trié est mis en cache entre les changements de page : appelez RefreshAsync() après une modification d'éléments sur place. |
KeyField | string | null | LgListView<TItem> | Propriété identifiant un élément : la sélection et l'élément actif comparent sur cette clé et survivent aux rechargements, et chaque élément garde ses composants (clé de rendu @key) quand il change de place. À défaut, une liste distante utilise la propriété Id du modèle s'il en a une, sinon l'égalité du type est utilisée. La clé suit un changement de la source de données (locale ou distante). |
Kind | Kind | Kind.Primary | LgListView<TItem> | Thème visuel du cadre de la liste. |
LinkSelector | Func<TItem, LgPageLink> | null | LgListView<TItem> | Page ouverte par un clic sur la carte d'un élément ; un élément avec un lien navigue sans déclencher OnItemClick ni changer l'élément actif. |
ListViewDataCounter | ListViewDataCounter | null | LgListView<TItem> | Compteurs du dernier chargement (ActiveRows, TotalPages, TotalRows), liables en two-way via ListViewDataCounterChanged. |
NoDataDescription | string | #lblListViewNoDataDesc | LgListView<TItem> | Description affichée quand la source ne contient aucun élément. |
NoDataTitle | string | #lblListViewNoDataTitle | LgListView<TItem> | Titre affiché quand la source ne contient aucun élément. |
PagerOnTop | bool | false | LgListView<TItem> | Affiche le pager au-dessus des éléments plutôt qu'en dessous. |
PaginationButtonCount | int | 5 | LgListView<TItem> | Nombre de boutons de page affichés par le pager. |
PaginationSizeSelector | int[] | { 10, 20, 50, 100 } | LgListView<TItem> | Tailles de page proposées ; la valeur 0 propose « Tout ». |
SelectableRows | bool | false | LgListView<TItem> | Active la sélection (case à cocher devant chaque élément). |
Selection | ICollection<TItem> | null | LgListView<TItem> | Collection mutable des éléments sélectionnés ; créée par le composant si elle est omise. |
ShowFilters | bool | false | LgListView<TItem> | Visibilité du panneau de filtres, liable en two-way via ShowFiltersChanged ; masquer le panneau conserve les valeurs des filtres. |
ShowFiltersSummary | bool | false | LgListView<TItem> | Résume les filtres actifs sous le titre (« Libellé : valeur », deux au plus puis « +N »), comme la grille, quand le panneau de filtres est masqué. |
SortOptions | RenderFragment | null | LgListView<TItem> | Déclarations de champs triables (composants LgListViewSort) ; le tri initial est celui marqué IsDefault="true", aucun sinon. |
StateId | string | null | LgListView<TItem> | Identifiant de persistance de l'état (tri, taille de page, filtres, panneau, groupes repliés) dans le stockage local du navigateur. |
StripeContent | RenderFragment<TItem> | null | LgListView<TItem> | Contenu rendu dans la bande de couleur de la carte par défaut (et de RenderStripe() dans ItemTemplate) ; donne une bande à tous les éléments. |
StripeCssClassSelector | Func<TItem, string> | null | LgListView<TItem> | Classes CSS de la bande de la carte (couleur du thème par exemple) ; la bande est rendue quand ce sélecteur, ColorSelector ou StripeIconSelector retourne une valeur, ou avec StripeContent. |
StripeIconSelector | Func<TItem, string> | null | LgListView<TItem> | Nom de l'icône affichée dans la bande de la carte ; une icône seule rend la bande, de la couleur du thème. |
Title | string | null | LgListView<TItem> | Titre affiché dans l'en-tête du cadre ; {0} (nombre total d'éléments) et {1} (éléments de la page) y sont remplacés par les compteurs du dernier chargement, ... tant qu'ils sont inconnus. |
TitleContent | RenderFragment | null | LgListView<TItem> | Contenu libre rendu après le titre dans l'en-tête. |
Toolbar | RenderFragment | null | LgListView<TItem> | Boutons ajoutés à la barre d'actions de l'en-tête, avant les boutons intégrés (filtres, tri). |
ToolbarSelection | RenderFragment | null | LgListView<TItem> | Contenu ajouté au panneau d'action affiché lorsqu'au moins un élément est sélectionné. |
TooltipIsHtml | bool | false | LgListView<TItem> | Interprète les infobulles de TooltipSelector au format HTML. |
TooltipSelector | Func<TItem, string> | null | LgListView<TItem> | Infobulle de la carte d'un élément. |
Virtualize | bool | false | LgListView<TItem> | Ne rend que les éléments visibles (ceux de la page courante avec AllowPaging). |
VirtualizeItemSize | float | 50 | LgListView<TItem> | Hauteur attendue d'un élément (en pixels) en rendu virtualisé. |
AriaLabel | string | null | LgAriaComponentBase | Libellé ARIA traduit du groupe racine. |
AriaLabelledBy | string | null | LgAriaComponentBase | Identifiant de l'él ément qui nomme le groupe racine. |
LgListViewSort<TItem>
Déclaration d'un champ triable dans la section SortOptions. Ce composant n'est jamais rendu : ses déclarations sont lues par la liste. TItem est déduit de la LgListView englobante.
| Nom | Type | Défaut | Déclaré dans | Description |
|---|---|---|---|---|
IsDefault | bool | false | LgListViewSort<TItem> | Fait de ce champ le tri initial ; sans déclaration par défaut, la liste n'est pas triée au départ. |
Key | string | null | LgListViewSort<TItem> | Clé du tri (état persisté, Key de OnSortChanged) ; par défaut le chemin du membre de SortSelector, obligatoire pour une expression calculée. |
SortSelector | Expression<Func<TItem, object>> | null | LgListViewSort<TItem> | Clé de tri par élément x => x.Membre (obligatoire). Une expression calculée ne fonctionne qu'en local. |
Text | string | null | LgListViewSort<TItem> | Libellé affiché dans le menu de tri ; par défaut le Name du [Display] du membre, puis la clé. |
LgListViewFilter<TItem, TValue>
Filtre du panneau Filters, rendu avec la boîte de filtre de LgGridView correspondant à TValue. TItem est déduit de la LgListView englobante et TValue de FilterSelector.
| Nom | Type | Défaut | Déclaré dans | Description |
|---|---|---|---|---|
FilterSelector | Expression<Func<TItem, TValue>> | null | LgListViewFilter<TItem, TValue> | Valeur filtrée x => x.Membre (obligatoire) ; son type choisit la boîte de filtre. Figée à l'initialisation. |
Items | IEnumerable<TValue> | null | LgListViewFilter<TItem, TValue> | Valeurs proposées par l'onglet « Sélection » ; à défaut, les valeurs de la source filtrées par les autres filtres. |
Key | string | null | LgListViewFilter<TItem, TValue> | Clé du filtre (état persisté, clés de OnFilterChanged) ; par défaut le chemin du membre de FilterSelector, obligatoire pour une expression calculée. |
Text | string | null | LgListViewFilter<TItem, TValue> | Libellé du filtre (panneau et résumé des filtres) ; par défaut le Name du [Display] du membre, puis la clé. |
LgListViewFilter reçoit en cascade la LgListView englobante : il ne peut être utilisé que dans la section Filters d'une LgListView (une exception est levée sinon).
Méthodes & événements
Méthodes publiques invocables via @ref :
| Méthode | Description |
|---|---|
RefreshAsync() | Recharge les données depuis la source (locale ou distante). Seul un chargement distant affiche l'indicateur de chargement : des éléments locaux sont mis à jour sur place (le focus est conservé). |
ClearFiltersAsync() | Vide tous les filtres puis recharge les données ; sans effet quand aucun filtre n'est actif. |
ExpandAllGroups() | Déplie tous les groupes (avec GroupSelector), comme le bouton « Déplier les groupes » ; persisté avec StateId. |
CollapseAllGroups() | Replie tous les groupes (avec GroupSelector), comme le bouton « Replier les groupes » ; persisté avec StateId. |
Événements :
| Événement | Type d'argument | Description |
|---|---|---|
ActiveItemChanged | TItem | Élément actif (binding two-way de ActiveItem), déclenché au clic sur une carte ou par ActivateAsync(). |
CollapsedChanged | bool | La liste a été repliée ou dépliée par un clic sur l'en-tête (binding two-way de Collapsed). |
CurrentPageChanged | int | Page courante (binding two-way de CurrentPage). |
ListViewDataCounterChanged | ListViewDataCounter | Compteurs mis à jour après chaque chargement (binding two-way de ListViewDataCounter). |
OnFilterChanged | ListViewFilterChangedEventArgs | L'ensemble des filtres actifs a changé, y compris à la restauration depuis StateId (Filters indexés par clé de filtre, HasFilters()). |
OnItemClick | TItem | Clic sur la carte d'un élément (après la confirmation et le changement d'élément actif) ; rend les cartes cliquables. |
OnItemDrop | ListViewDropEventArgs<TItem> | Un élément est relâché sur une position acceptée de cette liste (liste cible), avant la mise à jour des éléments : Cancel refuse le dépôt, Handled indique que le gestionnaire a mis à jour les éléments. Nécessaire au changement de groupe. |
OnItemDropped | ListViewDropEventArgs<TItem> | L'élément déposé est en place (éléments mis à jour, listes rechargées), sur la liste cible. |
OnRowSelection | ListViewSelectionEventArgs<TItem> | La sélection a changé (Selection, SelectedItem, SelectAction). |
OnSortChanged | ListViewSortEventArgs | Le tri a changé (Key : clé du tri, SortDirection — voir DataSortDirection ; Sorts : le même tri sous la forme de GridViewSortEventArgs.Sorts, 0 ou 1 élément). |
ShowFiltersChanged | bool | Visibilité du panneau de filtres (binding two-way de ShowFilters). |
Énumérations associées
ListViewFiltersPosition
Position du panneau de filtres, portée par FiltersPosition (défaut : Top).
| Valeur | Description |
|---|---|
Top | Panneau au-dessus des éléments, dans la liste. |
Popup | Fenêtre modale centrée, par-dessus la page. |
Left | Tiroir pleine hauteur glissant depuis le bord gauche de l'écran. |
Right | Tiroir pleine hauteur glissant depuis le bord droit de l'écran. |
ListViewDragMode
Capacités de glisser-déposer, portées par DragMode (drapeaux combinables, défaut : None).
| Valeur | Description |
|---|---|
None | Pas de glisser-déposer. |
Reorder | Les éléments peuvent être déplacés dans la liste ; sans effet quand la liste est triée. |
DragOut | Les éléments peuvent être glissés vers une autre liste du même DragGroup. |
DropIn | La liste accepte les éléments glissés depuis une autre liste du même DragGroup. |
Copy | Les éléments glissés vers une autre liste sont copiés : la liste les garde (avec DragOut). |
All | Reorder, DragOut et DropIn. |
ListViewSelectAction
Type de changement de sélection, porté par ListViewSelectionEventArgs<TItem>.SelectAction.
| Valeur | Description |
|---|---|
SelectItem | Sélection d'un élément. |
UnselectItem | Désélection d'un élément. |
SelectAll | Sélection de tous les éléments chargés. |
UnselectAll | Désélection de tous les éléments. |
SelectGroup | Sélection des éléments affichés d'un groupe (case à cocher de l'en-tête de groupe). |
UnselectGroup | Désélection des éléments affichés d'un groupe (case à cocher de l'en-tête de groupe). |
Bonnes pratiques / accessibilité
LgListViewrend un cadrerole="group"contenant une zonerole="list"et des élémentsrole="listitem".AriaLabeletAriaLabelledBynomment ce groupe (le titre garde son propre texte) : renseignez-les lorsque le titre visuel ne suffit pas.- Chaque case de sélection est nommée par le contenu de son élément (
aria-labelledby) : soignez le texte deItemTemplate, c'est lui qu'annonce un lecteur d'écran. La case « Tout sélectionner » est nommée par l'action qu'elle déclenche (« Tout sélectionner » / « Tout désélectionner »). - Ne placez pas la liste dans un
LgFrame: elle est déjà un cadre. - En mode distant ou paginé, la sélection a besoin d'une clé : renseignez
KeyField, sauf en mode distant si la propriétéIddu modèle identifie l'élément (clé par défaut). Sans clé, les instances rechargées ne sont plus égales aux instances sélectionnées. - Pour les données distantes volumineuses, combinez
VirtualizeavecAllowPaging: sans pagination, la virtualisation charge toute la source. - Dans
ItemTemplate, comme avecColorSelector/StripeContent, évitez de ne transmettre l'information que par la couleur ou l'icône : reprenez-la en texte dans le corps de la carte. - Les cartes cliquables sont focalisables et activables au clavier ; l'en-tête de groupe porte un bouton
aria-expandedpour le repli, et sa case à cocher un étataria-checked="mixed"quand le groupe est partiellement sélectionné. AvecGroupSelector, la zone des éléments de chaque groupe est unerole="list"nommée par la clé du groupe. - Ne transmettez pas l'état actif ou le statut d'un groupe seulement par la couleur (
ColorSelector,GroupColorSelector) : reprenez-le en texte. - Avec
DragMode, la poignée est un bouton nommé « Déplacer l'élément » et décrit par les consignes clavier ; le déplacement au clavier est annoncé par une régionaria-live. Proposez aussi une action sans glisser (bouton, menu) quand un élément doit changer de liste : le clavier ne réordonne que dans sa liste.
Consultez la Référence API — LgListView pour la liste générée des membres publics.
Composants liés
LgGridViewpour les tableaux de données en colonnes, l'édition en ligne, le regroupement multi-niveaux et l'export.LgFrame, le cadre dans lequel la liste est rendue (en-tête, repli,Kind).LgToolbaretLgToolbarButtonpour composer les actions d'en-tête ou de sélection.LgCardpour structurer le contenu de chaque élément.