Skip to content

TableView fr

Edgar Mesquita edited this page Oct 20, 2026 · 4 revisions

Vue de tableau

🌐 Cette page en : English · Português · Español · Français · Deutsch

TableView est une fenêtre sur une grille plus grande que n'importe quel écran, sur les DEUX axes, comme l'est le TableView de Flutter : vous décrivez jusqu'où va chaque ligne et chaque colonne, vous lui remettez un constructeur qui répond la cellule à une ligne et une colonne, et vous dites combien des premières lignes et colonnes restent épinglées. Il ne construit que les cellules à la vue plus une marge autour d'elles, si bien que la feuille entière d'Excel, 1 048 576 lignes sur 16 384 colonnes, coûte ce que coûte un écran. Il est write-once : le même C# tourne en peinture GPU sur Photon et en DOM sur le web.

TableView(
    rows: new UniformTableSpans(1_048_576 + 1, 28),
    columns: new SparseTableSpans(16_384 + 1, 96, new Dictionary<int, double> { [0] = 48, [3] = 180 }),
    cellBuilder: (row, column) => Text(row == 0 ? $"{column}" : $"{row}:{column}", TypeRole.Caption),
    pinnedRows: 1,
    pinnedColumns: 1,
    width: SizeValue.Fill,
    height: SizeValue.Fill,
    label: "Sheet")

L'écran /table du sample du dashboard est cette grille, chaque cellule montrant sa propre adresse, avec une ligne d'en-tête et une colonne de numéros de ligne épinglées.

Lignes et colonnes

Chaque axe est un TableSpans : combien de lignes (ou de colonnes) il y a, jusqu'où elles vont en tout, et les deux questions que pose le viewport, où commence l'index i (OffsetOf) et quel index se trouve à un décalage (IndexAt).

  • UniformTableSpans(count, extent) : chaque ligne (ou colonne) va aussi loin. Tout décalage est une multiplication.
  • SparseTableSpans(count, extent, extents) : une étendue par défaut, et les quelques-unes qui ont la leur, comme dans une feuille où quelqu'un a élargi la colonne D. Les exceptions sont gardées triées avec une somme cumulée, si bien qu'un décalage coûte une recherche binaire sur elles, aussi long que soit l'axe.
  • La vôtre : dérivez de TableSpans et répondez Count, Total, ExtentOf, OffsetOf et IndexAt.

Les décalages sont des double sur les deux cibles : un million de lignes de 28 atteignent 29 360 128, au-delà de ce qu'un float compte encore point par point.

La fenêtre qu'il construit

Le tableau construit les lignes et colonnes que montre le viewport plus overscan (3 par défaut) au-delà de chaque bord. La fenêtre a de l'hystérésis : un défilement qui garde ce qui est visible à l'intérieur des cellules déjà construites ne construit rien, et le viewport déplace ces cellules de lui-même. Le tableau ne construit de nouveau que lorsque les lignes ou colonnes visibles les quittent.

Une cellule a pour clé sa position ("row:column"), si bien qu'une cellule qui reste dans la fenêtre garde son élément, et son état, quand la fenêtre se déplace.

La première frame est construite pour une fenêtre courante (1 024 × 768) plutôt que pour rien, donc elle montre déjà des cellules ; le viewport rapporte ensuite sa taille réelle et la frame suivante construit pour elle.

Lignes et colonnes épinglées

pinnedRows et pinnedColumns gardent les premières lignes en haut et les premières colonnes au début pendant que le reste défile. Le viewport dessine quatre bandes, chacune sous son propre découpage : le coin, qui ne bouge jamais ; les lignes épinglées, qui se déplacent latéralement avec la grille ; les colonnes épinglées, qui descendent avec elle ; et le corps, qui bouge dans les deux sens. Une cellule est dessinée dans la bande de sa première ligne et de sa première colonne.

Marques

Les marks sont dessinées PAR-DESSUS les cellules, sur la plage que chacune couvre, et ne reçoivent ni appui ni focus : une sélection, un contour, la bande d'une recherche. Chacune est un TableViewCell fait avec mark: true, ses rows et columns disant combien de lignes et de colonnes elle couvre :

TableViewCell(row: 4, column: 2, Box(new BoxStyle { BorderWidth = 2, BorderColor = theme.FocusRing }),
    mark: true, rows: 3, columns: 2)

Une marque qui franchit le bord d'une bande épinglée y est coupée, un morceau par bande, si bien qu'elle se voit dans chaque bande qu'elle atteint et se cache là où elle passe sous une bande.

Défilement

Le viewport POSSÈDE son décalage, sur les deux cibles : le navigateur ne fait défiler rien. Ce n'est pas une question de goût. Un navigateur dessine un élément de 16 777 214 px de haut au plus, et les lignes d'Excel vont jusqu'à 29 millions, si bien qu'une grille que le navigateur ferait défiler ne pourrait jamais atteindre sa dernière ligne. Le tableau déplace ses cellules par transform à la place, et dessine ses propres barres de défilement.

  • Une molette et un trackpad déplacent les deux axes. Les deltas précis d'un trackpad déplacent la grille comme le font les doigts ; un cran de molette de souris glisse jusqu'à son arrivée. Maj tourne une molette verticale vers l'autre axe.
  • Les barres de défilement se tiennent dans des bandes sur les bords de fin et du bas. Un curseur se glisse, et un appui sur la piste déplace d'une page vers le pointeur.
  • Un doigt qui parcourt plus d'un slop de 12 points fait panoramiquer la grille, et un soulèvement pendant qu'elle bouge la lance avec de l'inertie. Un appui qui ne parcourt jamais de distance reste un toucher sur la cellule en dessous.
  • Ce que la grille ne peut pas absorber à un bord passe au scroller qui l'entoure, si bien qu'une page continue de défiler une fois la grille arrivée à sa fin.
  • Le clavier : le tableau est lui-même un arrêt de Tab, avant les contrôles de ses cellules. Avec le focus, les flèches avancent d'un pas, Page précédente et Page suivante d'une page, Début et Fin jusqu'à la première et la dernière ligne, et avec Contrôle ou Commande jusqu'à la première et la dernière colonne aussi. Tab visite les contrôles des cellules ligne par ligne.
  • Une souris ou le pointeur d'un trackpad sur un téléphone ou une tablette appuie sur les cellules, comme sur un ordinateur ; seul un doigt fait panoramiquer.
  • Avec le mouvement réduit, chaque pas arrive d'un coup.

request fait défiler pour vous, une fois par version :

request: new TableScrollRequest(version) { Reveal = new TableRange(1_048_575, 0) }

Offset met la grille à un décalage ; Reveal amène une plage à la vue, à l'écart des bandes épinglées. Une requête est honorée quand sa Version est nouvelle, si bien que remettre la même à chaque build ne fait rien deux fois. Elle tient jusqu'à ce que la personne déplace la grille, si bien qu'une mise en page qui se pose en deux passes, une ligne qui mesure le tableau avant et après ses frères fixes, la mène encore là où la dernière passe le dit.

onScrolled dit où en est la grille (un TableOffset, à l'horizontale et à la verticale) et onViewportChanged quelle taille a la partie dans laquelle les cellules défilent, chacun une fois par changement.

Lui donner une fenêtre

Un tableau EST une fenêtre, alors donnez-lui-en une : une taille fixe, ou SizeValue.Fill à l'intérieur de quelque chose qui a une taille. Un axe Fill sans borne, ce que remet à son contenu une page qui défile sur cet axe, prend l'étendue visible du scroller le plus proche qui l'entoure, ou celle de la fenêtre, et le journal de développement le dit une fois, en nommant l'étendue prise. Son propre contenu ne décide jamais de sa taille, et une largeur à lui plus grande que la place que son parent lui donne est ramenée à cette place, sur les deux cibles.

Accessibilité

Le viewport est un groupe nommé par label, au-dessus des cellules qu'il tient. Les cellules qu'il ne tient pas ne sont pas du tout dans l'arbre, sur aucune des deux cibles. Tab atteint les contrôles des cellules qu'il tient, et un contrôle qui reçoit le focus hors de la fenêtre défile jusqu'à être visible, dégagé des bandes épinglées. Une marque n'est jamais un arrêt de Tab, et un lecteur d'écran ne l'atteint pas.

Sous le composant

TableView est un composant au-dessus d'un nœud du vocabulaire, TableViewport, qui place les TableViewCell qu'on lui remet et porte le modèle de défilement (ITableScrollModel, implémenté par TableScroll). Un composant qui décide de sa propre fenêtre, comme le fera le Spreadsheet, peut composer le nœud directement avec le même modèle : les réalisateurs donnent au modèle la molette, le pointeur et l'horloge, et dessinent ce qu'il répond.

Clone this wiki locally