Microsoft-ui-xaml: Discussion : Modern WinUI DataGrid - Entrée requise

Créé le 28 oct. 2019  ·  81Commentaires  ·  Source: microsoft/microsoft-ui-xaml

Discussion : Grid de données WinUI moderne

Salut les membres de la communauté ! Nous avons vu que DataGrid a été un élément précieux de la boîte à outils de la communauté Windows pour beaucoup d'entre vous et nous sommes intéressés à le faire évoluer vers un contrôle WinUI natif (!!). J'ai besoin de votre aide pour déterminer ce qui serait nécessaire pour faire d'un DataGrid à grande échelle le meilleur possible.

Je veux entendre votre avis sur tout ce qui concerne DataGrid. Pour commencer, n'hésitez pas à répondre à autant de questions que vous avez le temps pour :

  1. Quels sont les éléments de la liste de souhaits que vous souhaitez pour DataGrid ?
  2. Où DataGrid peut-il s'améliorer en termes d'interface utilisateur, d'UX et de conception globale ?
  3. Qu'est-ce que vous aimez/n'aimez pas à propos de DataGrid ?
  4. Dans quels scénarios utilisez-vous DataGrid ?
  5. Y a-t-il des scénarios dans lesquels vous souhaiteriez qu'il puisse mieux s'intégrer ?

Merci d'avance à tous ! Voir les liens ci-dessous pour quelques rappels et contexte.

Liens connexes


Lisez la documentation DataGrid
Téléchargez et interagissez avec DataGrid via le téléchargement du package DataGrid Nuget
Rafraîchissez vos connaissances en consultant l' implémentation open source DataGrid existante

discussion

Commentaire le plus utile

Ma wishlist : pour moi une bonne grille de données inclut toutes les fonctionnalités suivantes par défaut. J'emprunte quelques captures d'écran du monde HTML.

Filtrez facilement toute la page avec le nombre de lignes préféré.

1

Sélectionner / Désélectionner les colonnes visibles , Tri des colonnes , Copier , Imprimer

2

Exportez les données dans un format spécifique.

3

Réorganisation des colonnes en faisant glisser la colonne.

4

Filtrage des colonnes

5

En-tête fixe - où l'en-tête reste en haut même lors du défilement

Détails de la ligne avec le modèle XAML pour plus de détails.

6

Groupement de lignes

7

Glisser-déplacer l'ordre des lignes

8

Les fonctionnalités ci-dessus, à mon avis, devraient être standard dans toutes les grilles de données.

Si vous voulez faire en sorte que datagrid se démarque du monde html, j'inclurais également ce qui suit. Je me retrouve plusieurs fois à regarder une grille de données, puis à m'installer sur une liste, car la grille de données n'a pas ces fonctionnalités.

Balayez latéralement la ligne pour inclure des fonctionnalités telles que modifier, supprimer, signaler, etc.

sideswipe

Les fonctionnalités ci-dessus gèrent principalement la "présentation des données", ce qui manque encore à WinUI, c'est ce que je pense devrait être une fonctionnalité native de WinUI (contrôle) comme le Microsoft Pivot Control. pour compléter la grille de données.

MS a déjà le code source pour cela et c'était un contrôle génial absolu à l'époque.

pivot1

https://www.youtube.com/watch?v=ZJIkQ9nebKY

Vous abordez maintenant la présentation et la visualisation des données qui devraient être le minimum pour différencier WinUI de toutes les fonctionnalités de base.

Plus important encore, il affiche vraiment la puissance des "applications natives" qui devraient inclure des animations impressionnantes et des commandes visuellement attrayantes qui sont puissantes et ont l'air vraiment cool.

Je peux aller plus loin et dire qu'après les fonctionnalités ci-dessus (visualisations), nous pouvons inclure des animations 2D/3D qui créent un concept de profondeur dans les données et nous emmèneront dans une stratosphère différente, mais je suppose que c'est pour un autre jour ; ))

uwp2

Tous les 81 commentaires

Plus de modes d'affichage. Jetez un œil à l'explorateur de fichiers et à ses vues d'icônes. Le DataGrid doit pouvoir afficher les icônes/éléments dans une grille avec regroupement, ainsi que les lignes et colonnes d'en-tête.

Je sais que cela n'est peut-être pas possible ou hors de portée - mais c'est un aspect de WinUI vs Win32 qui n'est pas aussi simple que 1:1 - et une version moderne de l'explorateur de fichiers ou des boîtes de dialogue de fichiers communs - peut avoir besoin d'un tel contrôle. Cela pourrait être ce contrôle, pas un contrôle personnalisé interne.

Ma wishlist : pour moi une bonne grille de données inclut toutes les fonctionnalités suivantes par défaut. J'emprunte quelques captures d'écran du monde HTML.

Filtrez facilement toute la page avec le nombre de lignes préféré.

1

Sélectionner / Désélectionner les colonnes visibles , Tri des colonnes , Copier , Imprimer

2

Exportez les données dans un format spécifique.

3

Réorganisation des colonnes en faisant glisser la colonne.

4

Filtrage des colonnes

5

En-tête fixe - où l'en-tête reste en haut même lors du défilement

Détails de la ligne avec le modèle XAML pour plus de détails.

6

Groupement de lignes

7

Glisser-déplacer l'ordre des lignes

8

Les fonctionnalités ci-dessus, à mon avis, devraient être standard dans toutes les grilles de données.

Si vous voulez faire en sorte que datagrid se démarque du monde html, j'inclurais également ce qui suit. Je me retrouve plusieurs fois à regarder une grille de données, puis à m'installer sur une liste, car la grille de données n'a pas ces fonctionnalités.

Balayez latéralement la ligne pour inclure des fonctionnalités telles que modifier, supprimer, signaler, etc.

sideswipe

Les fonctionnalités ci-dessus gèrent principalement la "présentation des données", ce qui manque encore à WinUI, c'est ce que je pense devrait être une fonctionnalité native de WinUI (contrôle) comme le Microsoft Pivot Control. pour compléter la grille de données.

MS a déjà le code source pour cela et c'était un contrôle génial absolu à l'époque.

pivot1

https://www.youtube.com/watch?v=ZJIkQ9nebKY

Vous abordez maintenant la présentation et la visualisation des données qui devraient être le minimum pour différencier WinUI de toutes les fonctionnalités de base.

Plus important encore, il affiche vraiment la puissance des "applications natives" qui devraient inclure des animations impressionnantes et des commandes visuellement attrayantes qui sont puissantes et ont l'air vraiment cool.

Je peux aller plus loin et dire qu'après les fonctionnalités ci-dessus (visualisations), nous pouvons inclure des animations 2D/3D qui créent un concept de profondeur dans les données et nous emmèneront dans une stratosphère différente, mais je suppose que c'est pour un autre jour ; ))

uwp2

Un bon point de départ est de regarder votre partenaire Telerik avec son RadDataGrid (UWP Open Source). Avec un de mes clients, je l'ai utilisé et ça marche vraiment bien. Il est hyper rapide et polyvalent. La seule chose qui est difficile est leur code, il n'y a aucun moyen de modifier quoi que ce soit de leur moteur sans une bonne compréhension de l'architecture.

Je m'attendrais à ce que le nouveau DataGrid soit aussi performant que Telerik.

Je suis très heureux de voir que l'équipe WinUI envisage un contrôle DataGrid.

Les améliorations les plus substantielles que j'aimerais voir d'un nouveau contrôle pour remplacer le Toolkit DataGrid :

  • La possibilité de récupérer un DataGridRow par index
  • Événements spécifiques aux DataGridRows eux-mêmes. Par exemple, DoubleTapped et RightTapped.
  • Défilement fluide
  • Validation d'entrée pour les renommages de cellules
  • Un DataGridColumn conçu spécifiquement pour les icônes de ligne
  • Personnalisation facile des couleurs, etc.

L'option d'avoir un bouton d'édition qui place des icônes déplaçables à côté de chaque ligne pour déplacer l'ordre serait une fonctionnalité utile. Ce serait également formidable de voir des ombres derrière la rangée se soulever et se déplacer (puisque l'un des principaux attributs de Fluent est la profondeur). De petites flèches haut et bas peuvent être utiles à côté de l'icône de déplacement pour déplacer les lignes plus facilement avec la souris. Si une ligne est déplacée à l'aide des flèches, une subtile animation de glissement serait une bonne idée. Avec la saisie tactile, l'option de maintenir une ligne et de la déplacer sans même avoir besoin d'appuyer sur le bouton d'édition peut également fonctionner. Je ne sais pas si cela est déjà pris en charge, mais je pouvais voir des cases à cocher de sélection comme dans l'explorateur de fichiers, indiquant clairement quels DataGrids prennent en charge la sélection de lignes et améliorent simplement l'expérience utilisateur globale. L'application de rappels iOS contient certaines de ces idées (exemples illustrés ci-dessous). L'application iOS Stocks propose également un type d'accord similaire avec des lignes mobiles. La plupart de ces idées fonctionneraient également très bien pour les colonnes.

123456

IMG_1820 (1)

@NoahFeller Ce type d'action est plus logique pour une vue en liste. Avec une vue Grille, vous ne réorganisez pas l'ordre, il devrait y avoir des options de tri mais l'utilisateur ne fait pas glisser les choses.

*Éditer
Après y avoir réfléchi un peu plus, je vois en quoi une telle option peut être utile. Cependant, je ne pense certainement pas que cela devrait être le comportement par défaut.

@NoahFeller Ce type d'action est plus logique pour une vue en liste. Avec une vue Grille, vous ne réorganisez pas l'ordre, il devrait y avoir des options de tri mais l'utilisateur ne fait pas glisser les choses.

*Éditer
Après y avoir réfléchi un peu plus, je vois en quoi une telle option peut être utile. Cependant, je ne pense certainement pas que cela devrait être le comportement par défaut.

Ouais tu as probablement raison @yaichenbaum. J'envisageais ces suggestions comme la possibilité d'effectuer un tri personnalisé et j'ai pensé que faire glisser pourrait être utile pour cela. Donc je suis d'accord, certainement pas par défaut mais cela pourrait être assez utile en option. Merci pour les commentaires!

La simplicité de la fonction table de données WPF en grille de données. En fait, je me bats depuis environ une semaine pour essayer de faire fonctionner une grille de données UWP comme je l'avais dans WPF, où je pouvais simplement lier une grille de données à une vue de données, puis remplir la vue de données à partir de SQL avec un datatable.defaultview. La grille vient alors d'afficher le tableau de données. C'était incroyablement simple à faire, et jusqu'à présent, UWP a rendu cela ridiculement compliqué.

faire traverser la plate-forme

Je voudrais demander un mode de sélection de cellule unique, style excel.
Le but ultime étant un mode avec le comportement exact d'un WinForms DataGridView.

Disposer d'un assortiment d'options de virtualisation pouvant prendre en charge différents cas d'utilisation (des options de virtualisation à défilement simple comme le recyclage à d'autres concepts comme la pagination des données)
Souvent (dans des contrôles de bureau similaires qui prennent en charge cela), certaines de ces options commencent à échouer lorsqu'elles sont utilisées avec des modèles personnalisés pour des colonnes avec des données uniques. Plus ils peuvent soutenir dans ces cas, mieux c'est.

Dans la mesure du possible, la proposition du contrôle de pagination n° 268 doit être synchronisée et tous les hooks requis doivent être ajoutés au contrôle DataGrid.

C'est une bonne nouvelle! J'attends quelque chose d'officiel sur le front DataGrid depuis un certain temps depuis qu'il est apparu dans la boîte à outils de la communauté. C'est vraiment le dernier contrôle manquant de WinUI 3.0 pour lequel la boîte à outils communautaire n'a pas de bonne alternative.

Premièrement, s'il vous plaît, ne réinventez pas la roue. Comme base, commencez par l'implémentation WPF du DataGrid (je sais que vous ne pouvez pas utiliser le code mais veuillez utiliser 100% de l'API) - PAS celui de Silverlight. Le WPF DataGrid était beaucoup plus complet et a moins de bogues dans mes tests.

En utilisant la boîte à outils communautaire DataGrid, j'ai également demandé les ajouts d'API suivants pour divers cas d'utilisation. Discussion ici :

  • RowPressed : Comme indiqué ci-dessus. Indique qu'une ligne a été enfoncée afin qu'un traitement supplémentaire ou un menu contextuel puisse se produire.
  • RowDoublePressed : Identique à RowPressed, juste la version double-clic.
  • ColumnHeaderPressed : se produit chaque fois qu'un en-tête de colonne est enfoncé. Doit avoir la priorité sur toutes les mises à jour internes de sens de tri. Cela permettra des menus de filtrage personnalisés ou des options de clic droit pour activer/désactiver les colonnes.
  • ColumnHeaderDoublePressed : Identique à ColumnHeaderPressed, juste la version double-clic.
  • ColumnHeaderWidthChanged : se produit chaque fois que l'utilisateur redimensionne la largeur d'un en-tête de colonne. Cela permettra de sauvegarder ces informations de manière propre. Ceci est généralement nécessaire lors de la restauration de l'état de l'interface utilisateur.

Je continue également à avoir beaucoup de problèmes avec la communauté qui a pris DataGrid pour réinitialiser la position de défilement en haut après la modification d'ItemsSource. Cela doit être corrigé afin que le décalage soit conservé comme dans WPF ; Cependant, nous devons également être en mesure de contrôler cela, c'est pourquoi je suggère également l'API suivante :

  • FirstRowInView() : renvoie la première ligne visible dans le DataGrid utilisé pour restaurer l'état.
  • VerticalOffset : Get/Set à nouveau pour restaurer l'état de la barre de défilement
  • HorizontalOffset : Get/Set pour restaurer l'état de la barre de défilement

@RBrid A également aidé avec quelques analyses ici :

Nouveaux événements suggérés et quelques améliorations aux événements préexistants :

| Événement | Commentaires |
| :--- | :--- |
| ContextRequestedForColumnHeader | Pour prendre en charge l'affichage d'un menu contextuel (ou d'un autre menu volant) lors d'un clic droit sur un en-tête de colonne. Identique à Windows.UI.Xaml.UIElement.ContextRequested mais pour les en-têtes de colonnes au lieu de l'intégralité du DataGrid. |
| ContextCanceledForColumnHeader | Identique à Windows.UI.Xaml.UIElement.ContextCanceled mais pour les en-têtes de colonnes au lieu de l'ensemble de DataGrid. |
| ContextRequestedForRow | Pour prendre en charge l'affichage d'un menu contextuel (ou d'un autre menu volant) lors d'un clic droit sur une ligne. Identique à Windows.UI.Xaml.UIElement.ContextRequested mais pour les lignes au lieu de l'intégralité du DataGrid. |
| ContextCanceledForRow | Identique à Windows.UI.Xaml.UIElement.ContextCanceled mais pour les lignes au lieu de l'intégralité du DataGrid. |
| RowTapped | Notez également le cas où vous appuyez sur une ligne déjà sélectionnée. |
| RowDoubleTapped | Identique à Windows.UI.Xaml.UIElement.DoubleTapped mais pour les lignes au lieu de l'intégralité du DataGrid. |
| RowRightTapped | Identique à Windows.UI.Xaml.UIElement.RightTapped mais pour les lignes au lieu de l'intégralité du DataGrid. Voir aussi ContextRequestedForRow . |
| PointerPressedInRow | Identique à Windows.UI.Xaml.UIElement.PointerPressed mais pour les lignes au lieu de l'intégralité du DataGrid. |
| PointerReleasedInRow | Identique à Windows.UI.Xaml.UIElement.PointerReleased mais pour les lignes au lieu de l'intégralité du DataGrid. |
| PointerMovedInRow | Identique à Windows.UI.Xaml.UIElement.PointerMoved mais pour les lignes au lieu de l'intégralité du DataGrid. Il est possible que PointerMovedInRow ne soit déclenché que lorsque le pointeur est capturé. |
| ColumnHeaderTapped | Notez également le cas où vous appuyez sur un en-tête de colonne déjà sélectionné. |
| ColumnHeaderDoubleTapped | Identique à Windows.UI.Xaml.UIElement.DoubleTapped mais pour les en-têtes de colonnes au lieu de l'intégralité du DataGrid. |
| ColumnHeaderRightTapped | Identique à Windows.UI.Xaml.UIElement.RightTapped mais pour les en-têtes de colonnes au lieu de l'ensemble de DataGrid. Voir aussi ContextRequestedForColumnHeader . |
| ColumnHeaderWidthChanged | Alternativement, il pourrait être nommé ColumnHeaderResized . Dans l'événement args, incluez une propriété booléenne qui spécifie si elle a été modifiée par l'utilisateur plutôt que modifiée par programme. Évidemment, les arguments d'événement doivent également spécifier l'en-tête de colonne qui a été redimensionné/modifié. |
| SortOrderChanged | Doit être déclenché lorsque la liste des en-têtes de colonnes sélectionnées change. Également déclenché lorsque l'une des colonnes sélectionnées bascule entre l'ordre croissant et l'ordre décroissant. Dans l'événement args, incluez une propriété booléenne qui spécifie si l'ordre de tri a été modifié par l'utilisateur plutôt que modifié par programme. Voir aussi événement préexistant Sorting . Je pense qu'un nouvel événement SortOrderChanged serait déclenché après le déclenchement de l'événement Sorting , si le tri n'est pas annulé. |
| Sorting | Existe déjà, mais envisagez d'ajouter une propriété booléenne réglable dans les arguments d'événement qui permet d'annuler la demande de tri. Par exemple, le tri peut être invalide ou impossible à effectuer et doit être annulé. Ajoutez également une propriété booléenne pour spécifier si le tri a été demandé par l'utilisateur ou par programmation. |
| ColumnSortDirectionChanged | Cet événement pourrait être créé, mais il pourrait être inutile si l'événement SortOrderChanged susmentionné est créé, si SortOrderChanged est également déclenché lorsque le sens de tri change. |
| ColumnDisplayIndexChanged | Existe déjà, mais veuillez envisager d'ajouter une propriété booléenne (dans les arguments d'événement) qui spécifie si elle a été modifiée par l'utilisateur ou modifiée par programme. Veuillez également expliquer pourquoi il est nécessaire d'avoir à la fois les événements ColumnDisplayIndexChanged et ColumnReordered . Vous pouvez également éliminer l'un de ces événements. |
| ColumnReordered | Existe déjà, mais veuillez envisager d'ajouter une propriété booléenne qui spécifie si elle a été modifiée par l'utilisateur ou modifiée par programme. |
| SelectionChanged | Existe déjà, mais veuillez envisager d'ajouter une propriété booléenne (dans les arguments d'événement) qui spécifie si elle a été modifiée par l'utilisateur ou modifiée par programme. |
| CopyingRowClipboardContent | Existe déjà, mais pensez à ajouter une propriété booléenne à l'événement args qui spécifie si l'opération est coupée au lieu de copier. Vous pouvez également créer un événement séparé pour la coupe. |
| CuttingRowClipboardContent | N'existe pas. Envisagez de créer un événement qui est déclenché lorsque l'utilisateur tente de couper des lignes (via le raccourci clavier control-X, le menu contextuel ou autre). Vous pouvez également créer la propriété booléenne susmentionnée qui permettrait à CopyingRowClipboardContent d'être déclenché à la fois pour les opérations de copie et de coupe |
| PastingRowClipboardContent | N'existe pas. Envisagez de créer un événement déclenché lorsque l'utilisateur tente de coller (via le raccourci clavier control-V, le menu contextuel ou autre). |

Je pense que la fonctionnalité la plus importante pour moi serait la possibilité de gérer facilement un million de lignes ou plus, sans avoir à charger un million de lignes en mémoire. L'interface ISupportIncrementalLoading n'est pas assez bonne pour cela, car la barre de défilement ne reflète que le nombre de lignes que vous avez chargées jusqu'à présent (pas le nombre total), et pour atteindre la ligne 1 million, vous devrez continuer à faire défiler jusqu'à la fin et encore et charger de plus en plus de données, et j'espère que je ne manquerai pas de mémoire. Mais si je sais que j'ai 1 million d'enregistrements de données, laissez-moi le dire à la grille de données, et si je fais défiler rapidement ou si je saute jusqu'à la fin, on peut me demander de fournir uniquement les dernières lignes.
Pensez à faire défiler une liste de lignes dans une base de données que je vais extraire dynamiquement.

Je pense que la fonctionnalité la plus importante pour moi serait la possibilité de gérer facilement un million de lignes ou plus, sans avoir à charger un million de lignes en mémoire. L'interface ISupportIncrementalLoading n'est pas assez bonne pour cela, car la barre de défilement ne reflète que le nombre de lignes que vous avez chargées jusqu'à présent (pas le nombre total), et pour atteindre la ligne 1 million, vous devrez continuer à faire défiler jusqu'à la fin et encore et charger de plus en plus de données, et j'espère que je ne manquerai pas de mémoire. Mais si je sais que j'ai 1 million d'enregistrements de données, laissez-moi le dire à la grille de données, et si je fais défiler rapidement ou si je saute jusqu'à la fin, on peut me demander de fournir uniquement les dernières lignes.
Pensez à faire défiler une liste de lignes dans une base de données que je vais extraire dynamiquement.

Cette.

« moderne » signifie léger et rapide, et les applications d'entreprise consistent généralement à trier des tonnes de données internes pour rechercher et explorer les enregistrements appropriés. Pagination, tri, chargement incrémentiel asynchrone, défilement sans fin - tous ces éléments sont des éléments de base des applications de bureau qui exploitent les grilles de données.

MS devrait produire un exemple d'application qui met en évidence ces fonctionnalités dans la nouvelle grille et collecter les commentaires des développeurs d'entreprise au fil du temps pour améliorer ces expériences. Faites-le fonctionner à partir d'un grand ensemble de données comme World Wide Importers pour démontrer son efficacité.

@dotMorten

Je pense que la fonctionnalité la plus importante pour moi serait la possibilité de gérer facilement un million de lignes ou plus, sans avoir à charger un million de lignes en mémoire.

Je le souhaite aussi. Afin d'aider à prendre en charge un million de lignes (et je veux dire assister, pas nécessairement la solution complète), je suggère que DataGrid rende facultative sa technique de liaison de données actuelle. Je pense qu'actuellement la liaison de données est obligatoire (à moins que mes connaissances ne soient plus à jour avec la dernière version de DataGrid). DataGrid ne devrait pas nécessiter l'utilisation de Windows.UI.Xaml.Data.Binding comme seul moyen pris en charge de récupérer les valeurs pour chaque cellule/colonne dans chaque ligne visible.

Je suggère que DataGrid permette aux applications de donner à DataGrid un délégué ou une instance d'interface que DataGrid invoquera chaque fois que DataGrid a besoin de récupérer la valeur d'une cellule/colonne dans une ligne (autrement, ce délégué ou cette interface pourrait récupérer la ligne entière - toutes les valeurs de colonne pour une ligne spécifiée).

Idéalement (si possible), DataGrid permettrait à ce délégué ou à cette interface de fonctionner de manière asynchrone . Par exemple, le délégué ou l'interface peut renvoyer un Task ou IAsyncOperation<TResult> au lieu de renvoyer immédiatement la valeur demandée.

Alternativement, la prise en charge asynchrone est également possible sans Task et IAsyncOperation<TResult> , si DataGrid fonctionne de la même manière que la procédure suivante :

  1. DataGrid décide qu'il doit récupérer la valeur de la cellule/colonne 5 dans l'ID de ligne 50001. Alternativement, DataGrid décide de récupérer toutes les valeurs de colonne pour l'ID de ligne 50001.
  2. DataGrid appelle un délégué ou une instance d'interface ou un gestionnaire d'événements qui notifie à l'application que DataGrid a demandé le chargement des valeurs de données de la colonne/ligne spécifiée ou de la ligne entière.
  3. L'application récupère les données de ligne demandées de manière asynchrone. Par exemple, il pourrait effectuer de manière asynchrone une requête de base de données SQL.
  4. L'application termine de récupérer les données de ligne demandées. L'application appelle une méthode dans DataGrid qui donne les données de ligne à DataGrid.
  5. DataGrid affiche les données de la ligne ou fait tout ce qu'il faut pour faire avec les données.

Tout d'abord, wow !! Merci beaucoup à tous ceux qui apportent leurs idées. J'ai quelques réponses spécifiques ci-dessous, mais dans l'ensemble, je voulais dire que j'économise une tonne de ces commentaires et que j'apprécie vraiment d'entendre comment nous pouvons créer un DataGrid moderne et génial. Laisse le venir!

@Pinox merci beaucoup pour cette réponse détaillée et les captures d'écran. Votre liste de souhaits est géniale (surtout ces animations sympas !) - Je suis d'accord que ces fonctionnalités trouvées en html sont un bon point d'inspiration et sont simples mais amélioreraient considérablement la qualité de vie. Je garderai certainement ce commentaire pour référence future!

@verelpode , @robloo , @duke7553 OUI aux événements spécifiques à DataGrid ! Merci à tous pour les détails que vous mettez dans ces derniers. Comme nous concevons pour le toucher d'abord et pour une variété d'entrées, des événements comme ceux-ci doivent absolument être mis en œuvre !

@dotMorten , @jkewley , @verelpode La performance est certainement l'une des principales motivations de ce projet et l'une des principales améliorations que nous souhaitons mettre en œuvre, à travers une nouvelle histoire de virtualisation des données et l'utilisation de contrôles modernes tels que ItemsRepeater. Nous vous tiendrons tous au courant une fois que nous aurons plus de détails - mais merci encore pour ces détails que vous avez suggérés.

@Laz3rPanth3r , @robloo , @keeganatorr Nous vous entendons haut et fort sur le fait d'aimer les DataGrids qui appartiennent à WPF et à d'autres frameworks d'interface utilisateur - nous en tenons certainement compte dans cette actualisation !

Merci pour l'excellent travail sur DataGrid et la demande de commentaires ! Voici quelques autres améliorations suggérées.

Besoin de plus de sous-classes de DataGridColumn

Les sous-classes/implémentations actuelles de DataGridColumn sont insuffisantes. Je suggère de créer les nouvelles sous-classes suivantes de DataGridColumn :

| Sous-classe proposée | Descriptif |
| :--- | :--- |
| DataGridIconColumn | Une exigence commune est d'afficher une icône dans chaque ligne d'une liste, donc je suggère de créer une sous-classe DataGridColumn nommée DataGridIconColumn qui transtype la valeur de la cellule récupérée en Windows.UI.Xaml.Controls.IconSource et rend le Instance IconSource (une instance IconSource est rendue dans chaque cellule). |
| DataGridImageColumn | DataGridImageColumn devrait fonctionner de la même manière que le DataGridIconColumn proposé sauf qu'il devrait rendre Windows.UI.Xaml.Media.ImageSource au lieu de Windows.UI.Xaml.Controls.IconSource . |
| DataGridDateTimeColumn | Affiche la date et/ou l'heure, selon les paramètres. Convertit la valeur de la cellule en System.DateTimeOffset ou System.DateTime (tous deux pris en charge) et la convertit en texte à afficher dans la cellule. La conversion en texte doit être contrôlée par les paramètres/propriétés de formatage dans la classe DataGridDateTimeColumn . Évidemment, le tri par date/heure doit également être pris en charge. |
| DataGridTimeSpanColumn | Convertit la valeur de la cellule en System.TimeSpan et la convertit en texte à afficher dans la cellule. La conversion en texte doit être contrôlée par les paramètres/propriétés de formatage dans la classe DataGridTimeSpanColumn . Évidemment, le tri doit également être pris en charge et il doit trier les instances de TimeSpan non le texte affiché. |
| DataGridDataSizeColumn | Convertit la valeur de la cellule en System.Int64 , UInt64 , Int32 ou UInt32 (tous pris en charge) et la convertit en une taille en octets (sous forme de texte ) à afficher. Par exemple, 1572864 s'afficherait sous la forme "1,5 Mo" car 1572864/1024/1024 = 1,5. La conversion en texte doit être contrôlée par les paramètres/propriétés de la classe DataGridDataSizeColumn . Le tri doit être effectué en utilisant la valeur entière d'origine et non le texte affiché. |
| DataGridCustomColumn | Cela devrait fonctionner de la même manière que le DataGridTemplateColumn préexistant, sauf sans le Windows.UI.Xaml.DataTemplate . Il doit invoquer un délégué/rappel ou un événement pour générer et/ou mettre à jour le sous-arbre d'éléments GUI affiché. |
| DataGridTextColumn | Existe déjà, mais pensez à ajouter des propriétés ou des événements qui permettent aux applications de remplacer la conversion objet-texte et la fonction de comparaison pour le tri. J'explique cela plus en détail plus tard dans mon message. |

DataGridCustomColumn ressemblerait à ceci :

public class DataGridCustomColumn : DataGridColumn
{
    public event EventHandler<DataGridDisplayingCellEventArgs> DisplayingCell;
}

public class DataGridDisplayingCellEventArgs : EventArgs
{
    public DataGridColumn Column { get; }
    public object CellValue { get; }
    public Windows.UI.Xaml.UIElement CellUIElement { get; set; } // settable
}

Lorsque l'événement DataGridCustomColumn.DisplayingCell est déclenché, le gestionnaire d'événements doit générer ou mettre à jour son propre sous-arbre UIElement pour afficher le DataGridDisplayingCellEventArgs.CellValue , et définir la propriété DataGridDisplayingCellEventArgs.CellUIElement sur cela UIElement sous-arborescence, puis DataGrid l'affichera.

La prochaine fois que DataGrid déclenche cet événement, DataGrid doit définir la propriété DataGridDisplayingCellEventArgs.CellUIElement sur l'instance UIElement qui a été précédemment générée par le gestionnaire d'événements, afin de permettre au gestionnaire d'événements de réutiliser/recycler et mettre à jour le même sous-arbre UIElement (potentiellement avec une valeur différente dans DataGridDisplayingCellEventArgs.CellValue ). Le gestionnaire d'événements est autorisé à recycler le même sous-arbre UIElement OU à définir la propriété DataGridDisplayingCellEventArgs.CellUIElement sur un sous-arbre UIElement nouvellement créé.

Envisagez également la possibilité de créer le nouvel événement DisplayingCell directement dans la classe de base DataGridColumn , au lieu de créer la sous-classe DataGridCustomColumn . Ainsi, l'événement DataGridColumn.DisplayingCell pourrait permettre la personnalisation ou le remplacement des UIElement générés pour chaque sous-classe de DataGridColumn .

Dans le DataGridTextColumn préexistant, la valeur/l'objet de la cellule est actuellement converti en texte à afficher en appelant System.Object.ToString . Veuillez envisager de créer un délégué/rappel ou un événement qui permet aux applications de remplacer cette conversion valeur-texte. Veuillez également considérer une propriété qui permet aux applications de spécifier une instance System.Collections.IComparer pour remplacer le comportement de tri.

public class DataGridTextColumn : DataGridColumn
{
    public System.Collections.IComparer Comparer { get; set; }
    public DataGridCellValueToToStringConverter CellValueToToStringConverter { get; set; }
}

public delegate string DataGridCellValueToToStringConverter(object sourceObject);

Alternativement, au lieu de créer la propriété Comparer dans DataGridTextColumn , envisagez la possibilité de créer la propriété Comparer directement dans la classe de base DataGridColumn , afin de permettre apps pour contrôler le comportement de tri pour toutes les sous-classes de DataGridColumn .

De même, la propriété CellValueToToStringConverter pourrait également être créée dans la classe de base DataGridColumn car il serait utile de pouvoir convertir n'importe quelle valeur de cellule en texte quelle que soit la sous-classe de DataGridColumn est utilisé. Par exemple, lors de la copie d'une ligne dans le presse-papiers, chaque valeur de cellule peut être convertie en texte. (Les formats texte et non-texte peuvent être placés simultanément dans le presse-papiers - les applications le font généralement afin d'augmenter la compatibilité avec d'autres applications.)

Re trier lorsqu'un DataGridIconColumn ou DataGridImageColumn est sélectionné : il est évident que DataGrid ne peut pas trier les icônes ou les images, il peut donc utiliser l'une de ces solutions :

  • Interdisez simplement aux utilisateurs finaux de sélectionner (trier par) un en-tête de colonne de type DataGridIconColumn ou DataGridImageColumn .
  • Créez une propriété AlternativeText dans la classe IconSource . Lorsque DataGridIconColumn trie les lignes, ou lorsqu'il convertit la cellule en texte pour le presse-papiers/copie, il utilise la propriété AlternativeText .
  • Créez une propriété réglable Comparer (de type System.Collections.IComparer ) soit en DataGridColumn soit en DataGridIconColumn .

Accès aux lignes/éléments sélectionnés

Veuillez envisager d'améliorer la fonctionnalité d'obtention et de définition des lignes/éléments sélectionnés, car la fonctionnalité actuelle est insuffisante. Actuellement ces propriétés existent :

public int SelectedIndex { get; set; }
public object SelectedItem { get; set; }
public System.Collections.IList SelectedItems { get; }

J'ai découvert que parfois j'avais besoin d'accéder aux instances DataGridRow des lignes sélectionnées, j'espère donc que les propriétés suivantes pourront être ajoutées à DataGrid :

public DataGridRow SelectedRow { get; set; }
public IList<DataGridRow> SelectedRows { get; }

Alternativement, si ce qui précède est trop difficile à mettre en œuvre, la variante en lecture seule suivante est moins puissante mais toujours utile :

public DataGridRow SelectedRow { get; }
public IReadOnlyCollection<DataGridRow> SelectedRows { get; }

Si les instances DataGridRow peuvent être recyclées , la documentation des propriétés ci-dessus doit avertir que les informations renvoyées ne sont que temporairement valides, elles doivent donc être lues/utilisées immédiatement et ne pas être conservées plus longtemps.

De plus, la propriété SelectedIndex préexistante donne accès à un index sélectionné, mais qu'en est-il de l'accès à tous les éléments sélectionnés ? Par conséquent, je suggère de créer la propriété SelectedIndexes :

public IList<int> SelectedIndexes { get; } // Suggestion.
public int SelectedIndex { get; set; } // Already exists.

Personnellement, je trouve le nom "SelectedIndex" déroutant car DataGrid est souvent utilisé en conjonction avec une base de données et le terme "index" a un sens complètement différent dans une base de données, donc je suggère de renommer les propriétés comme suit, mais je m'attends à ce que ma suggestion de nom sera rejeté :

public IList<int> SelectedOrdinals { get; }
public int SelectedOrdinal { get; set; }

Je souhaite également avoir la possibilité de faire défiler le DataGridRow et/ou le DataGridColumn spécifié. Actuellement cette méthode existe :

public void ScrollIntoView(object item, DataGridColumn column);

Je suggère de remplacer la méthode ScrollIntoView préexistante par ces 2 méthodes :

public void ScrollIntoView(DataGridRow row, DataGridColumn column);
public void ScrollItemIntoView(object item, DataGridColumn column);

Obtenez et définissez l'ordre de tri en un seul coup

Lorsque les applications sont ouvertes et fermées, elles doivent pouvoir enregistrer et restaurer la configuration de l'utilisateur final du DataGrid, y compris l'ordre de tri et d'autres paramètres. Ordre de tri, c'est-à-dire la liste des colonnes qui ont été sélectionnées par l'utilisateur. Notez qu'il s'agit d'une liste, pas d'une seule colonne. Plusieurs colonnes peuvent être sélectionnées simultanément, c'est-à-dire la colonne principale pour le tri, et la colonne secondaire pour le tri, et la colonne tertiaire pour le tri, etc.

Par conséquent, la propriété suivante pourrait être créée dans DataGrid, mais en fait, ce n'est que la première idée et ce n'est pas idéal :

public IReadOnlyList<DataGridColumn> SortOrder { get; set; }

Ce qui précède n'est pas idéal car il ne prend pas en charge la sauvegarde et la restauration des DataGridColumn.SortDirection de chaque colonne en un seul clic . Je me rends compte que les applications peuvent le faire en plusieurs étapes :

  1. Définissez la propriété SortOrder proposée sur la liste des colonnes sélectionnées.
  2. Définissez la propriété SortDirection de chacune des colonnes sélectionnées (répétez cette étape pour chaque colonne).

C'est toujours problématique car il s'agit de plusieurs occurrences, ce qui signifie que cela provoque plusieurs recours chronophages du DataGrid. Les utilisateurs finaux peuvent remarquer et subir un retard important dans un DataGrid qui contient un grand nombre de lignes, lorsque le DataGrid est utilisé plusieurs fois inutilement. Pour éliminer ce problème, je suggère la solution suivante qui permet aux applications de restaurer l'ordre de tri complet en un seul coup et de ne provoquer qu'un seul recours.

public class DataGrid
{
    public IReadOnlyList<DataGridColumnAndDirection> SortOrder { get; set; }
    ...
}

public struct DataGridColumnAndDirection
{
    public readonly DataGridColumn Column;
    public readonly DataGridSortDirection SortDirection;
    public DataGridColumnAndDirection(DataGridColumn, DataGridSortDirection) { ... }
}

Remarque J'ai délibérément écrit IReadOnlyList<DataGridColumnAndDirection> non IList<DataGridColumnAndDirection> ci-dessus, car les applications ne devraient pas pouvoir modifier la liste renvoyée par la propriété SortOrder . Au lieu de modifier la liste, les applications doivent définir la propriété SortOrder sur une liste que DataGrid copiera et utilisera pour remplacer complètement la liste d'ordre de tri. Ainsi, il fonctionnerait en un seul coup et éviterait plusieurs stations balnéaires coûteuses.

Lorsque DataGrid.SortOrder est défini sur une nouvelle liste, DataGrid définit également la propriété DataGridColumn.SortDirection dans chaque colonne de la nouvelle liste SortOrder , mais sans provoquer plusieurs stations. Ainsi DataGrid.SortOrder[i].SortDirection équivaut à DataGridColumn.SortDirection .

Obtenir et définir l'ordre des colonnes affichées en un seul clic

Lorsque les applications sont ouvertes et fermées, elles doivent pouvoir enregistrer et restaurer l'ordre des colonnes de l'utilisateur final, de préférence en un seul clic. Je sais que la propriété préexistante DataGridColumn.DisplayIndex est réglable, donc théoriquement, les applications pourraient restaurer la configuration de l'utilisateur final en parcourant toutes les colonnes de DataGrid.Columns et définir le DisplayIndex de chacune, mais cela peut provoquer des bugs. Par exemple, DisplayIndex peut échouer ou se comporter de manière inattendue lorsqu'une application doit définir temporairement le DisplayIndex d'une colonne sur le même DisplayIndex d'une autre colonne. De plus, s'il n'est pas effectué en un seul coup, cela pourrait déclencher plusieurs recalculs et/ou recalculs coûteux.

Par conséquent, je suggère de créer une propriété ColumnDisplayOrder dans DataGrid :

public IReadOnlyList<DataGridColumn> ColumnDisplayOrder { get; set; }

Comme je l'ai mentionné précédemment pour SortOrder , ColumnDisplayOrder est délibérément IReadOnlyList<DataGridColumn> non IList<DataGridColumn> car il devrait fonctionner en un seul coup.
Lorsque DataGrid.ColumnDisplayOrder est défini sur une nouvelle liste, DataGrid met à jour les DataGridColumn.DisplayIndex de chaque colonne pour correspondre.

Autoriser les utilisateurs finaux à masquer/afficher des colonnes

Conformément aux propriétés préexistantes DataGridColumn.CanUserReorder etc, je suggère de créer une propriété CanUserChangeVisibility dans DataGridColumn . Lorsque DataGridColumn.CanUserChangeVisibility est vrai, l'utilisateur final peut modifier la propriété DataGridColumn.Visibility .

Prend en charge les éléments de l'interface graphique générés dynamiquement lors de l'exécution

Autoriser la génération de l'interface graphique des détails de la ligne sans nécessiter l'utilisation de DataGrid.RowDetailsTemplate ( Windows.UI.Xaml.DataTemplate ). Pour y parvenir, il faut réfléchir à l'API, mais voici ma première idée de comment le faire : peut-être le faire via l'événement préexistant DataGrid.LoadingRow en changeant la propriété DataGridRowDetailsEventArgs.DetailsElement être réglable afin que le gestionnaire d'événements puisse générer (ou mettre à jour) l'UIElement par lui-même et le transmettre à DataGrid en définissant la propriété DetailsElement .

La raison pour laquelle l'utilisation obligatoire de Windows.UI.Xaml.DataTemplate est un problème : bien que les modèles soient une bonne fonctionnalité, le concept de modèle attend un extrait/document XAML pré-créé et invariable qui a été écrit par le développeur à l'avance. Ainsi, les modèles sont un problème lorsque l'application doit générer dynamiquement l'interface graphique lors de l'exécution. Ainsi, je souhaite les alternatives susmentionnées à DataTemplate .

Glisser-déposer des lignes, vers l'intérieur et vers l'extérieur

Je suggère de créer la possibilité d'activer éventuellement le glisser-déposer de lignes sortantes. DataGrid implémenterait le glisser mais pas le déposer. Lorsque la suppression se produit, DataGrid déclenche un événement et l'application répond à l'événement afin d'effectuer l'action souhaitée lorsque la ligne est supprimée en dehors du DataGrid.

Également la possibilité d'activer en option le glisser-déposer entrant de lignes ou d'éléments/objets. DataGrid accepte le glisser-déposer entrant mais n'implémente pas le dépôt. DataGrid déclencherait un événement lorsque la ligne/l'élément/l'objet est supprimé, et l'application répond à l'événement afin d'effectuer l'action souhaitée lorsque la ligne est supprimée à l'intérieur du DataGrid.

Arrière-plans de cellules individuelles

Nous avons une demande de fonctionnalité d'un client qui souhaite que des cellules individuelles soient supprimées (en changeant la couleur/le pinceau d'arrière-plan de la cellule) à certains moments (par exemple, lorsque notre application détecte des changements ou des valeurs importantes ou des valeurs dangereuses dépassant les limites de sécurité, etc.).

Ainsi je pourrais proposer une propriété DataGridCell.Background (de type Brush ), mais je pense que cette façon de faire est probablement défectueuse car DataGrid recycle les instances DataGridCell , n'est-ce pas ? Je suppose donc que l'activation de cellules individuelles en définissant une propriété DataGridCell.Background serait une solution peu fiable.

Une meilleure façon pourrait être via l'événement DataGridColumn.DisplayingCell que j'ai proposé dans mon message précédent. Le gestionnaire d'événements pourrait définir une propriété CellBackgroundBrush dans DataGridDisplayingCellEventArgs .

Récupération de données par DataGrid Dumb-down (valeurs de cellules)

Je sais que "stupide" sonne très mal, mais en réalité, j'aimerais que DataGrid soit rendu muet dans le domaine de la récupération de données (récupération des valeurs de cellule à afficher par DataGrid).

Actuellement, DataGrid tente d'effectuer la récupération de données de manière pratique et automatique via sa propriété DataGrid.ItemsSource ainsi que des techniques de liaison de données (la propriété DataGridBoundColumn.Binding ) et des interfaces telles que System.ComponentModel.INotifyPropertyChanged .

Oui, la liaison de données est une fonctionnalité pratique, mais en fait, je préférerais de loin que DataGrid fasse _moins_ dans ce département ! Plusieurs composants Microsoft me causent en fait de grandes difficultés via leur comportement consistant à essayer d'être intelligent mais qui finissent par être trop intelligent . Dans l'ensemble, j'aurais en fait moins de difficultés et moins de travail si ces composants cessent d'essayer d'être aussi intelligents/automatiques/pratiques. Lors de la conception d'un comportement automatique, je trouve qu'il vaut la peine de garder à l'esprit que l'automatique sonne bien mais a le potentiel de se retourner contre lui.

_"Laissez-moi simplement le faire par moi-même."_
Parfois, la meilleure solution consiste simplement à autoriser les applications à effectuer la tâche par elles-mêmes, au lieu d'essayer et d'échouer de le faire "automatiquement" à l'intérieur d'un composant tel que DataGrid. Je souhaite que DataGrid me permette d'effectuer complètement la récupération des données par moi-même, au lieu d'essayer de récupérer automatiquement les données via les propriétés DataGridBoundColumn.Binding et DataGrid.ItemsSource .

Idéalement, j'aimerais éliminer l'obligation d'utiliser la propriété DataGrid.ItemsSource pour fournir les articles. @dotMorten a mentionné un million de lignes. Actuellement, DataGrid oblige les applications à définir DataGrid.ItemsSource , mais il est peu pratique de créer un objet de liste contenant un million d'éléments. Ainsi, je souhaite que DataGrid cesse d'être intelligent dans le département de récupération de données et me laisse plutôt effectuer la récupération de données par moi-même, sans utiliser DataGridBoundColumn.Binding et DataGrid.ItemsSource .

@anawishnoff a écrit :

La performance est certainement l'une des principales motivations de ce projet et l'une des principales améliorations que nous souhaitons mettre en œuvre, à travers une nouvelle histoire de virtualisation des données et l'utilisation de contrôles modernes tels que ItemsRepeater.

Je vois que vous avez dit que la nouvelle histoire de virtualisation des données améliorera les performances, et c'est une bonne nouvelle, mais cela éliminera-t-il également l'obligation d'utiliser la propriété DataGridBoundColumn.Binding afin de fournir les valeurs de cellule que DataGrid affiche ?

Si l'intégralité du travail de récupération de données est sous - @dotMorten . Dumb it down, s'il vous plaît :sourire:

Quelques fonctionnalités inutiles dans WPF DataGrid ?

La version WPF de DataGrid comporte quelques fonctionnalités qui semblent inutiles ou peu pratiques, et ces fonctionnalités pourraient être ignorées dans WinUI DataGrid, mais je m'attends à ce que certaines personnes aient probablement une opinion différente sur ces fonctionnalités.

Combien de personnes s'opposeraient si WinUI DataGrid abandonnait la fonctionnalité permettant aux utilisateurs finaux de modifier les valeurs des cellules en ligne/directement à l'intérieur du DataGrid ? Dans notre cas, à chaque endroit où nous utilisons DataGrid, nous définissons toujours DataGrid.IsReadOnly sur true pour désactiver la fonction d'édition en ligne/directe. Nous permettons aux utilisateurs de modifier la ligne sélectionnée dans un volet ou un panneau séparé, ou dans RowDetails ( DataGrid.RowDetailsTemplate ), mais pas directement dans le DataGrid lui-même.

Il semble que WinUI DataGrid ait déjà évolué dans le sens de la suppression de la prise en charge de l'édition en ligne/directe, car WPF DataGrid avait CanUserAddRows et CanUserDeleteRows mais ces propriétés n'existent plus dans WinUI DataGrid. Pourquoi ne pas aller jusqu'au bout pour supprimer complètement la fonction d'édition en ligne/directe ? Combien de personnes ont des objections à cette idée ?

Sélection de cellules individuelles : WPF DataGrid a une propriété SelectionUnit que vous pouvez définir sur Cell , FullRow ou CellOrRowHeader . Dans notre cas, nous l'avons toujours défini sur FullRow et n'avons jamais eu besoin de le définir sur Cell . Cependant, je vois qu'une personne ici a déjà demandé le mode de sélection de cellule unique. Ma question est de savoir si le mode de sélection de cellule est une demande courante ou rare.

D'un autre côté, la sélection de cellules individuelles peut être utile lorsque l'utilisateur copie des lignes/cellules dans le presse-papiers. Cela permettrait aux utilisateurs de copier une cellule individuelle (ou plusieurs cellules contiguës) dans le presse-papiers au lieu de copier la ligne entière. Cependant, je ne sais pas si cette fonctionnalité est vraiment utile ou non.

| Fonctionnalité douteuse dans WPF | Commentaires |
| :--- | :--- |
| DataGrid.IsReadOnly | Peut-être qu'il n'est pas vraiment nécessaire de définir IsReadOnly sur false ? |
| DataGrid.CanUserAddRows | N'existe pas dans WinUI DataGrid. Déjà abandonné, ou peut-être pas encore mis en œuvre (je ne connais pas le plan). |
| DataGrid.CanUserDeleteRows | N'existe pas dans WinUI DataGrid. Déjà abandonné, ou peut-être pas encore mis en œuvre (je ne connais pas le plan). |
| DataGrid.SelectionUnit | N'existe pas dans WinUI DataGrid. |

Wow, discussion incroyable ici. ️

J'accepte également l'API WPF DataGrid. Le WPF DataGrid est vraiment le DataGrid que je veux pour WinUI 3.0.

Mais même le WPF DataGrid manque de certaines fonctionnalités. Dans le passé, la plupart de mes clients utilisaient un DataGrid tiers plus puissant pour obtenir ces fonctionnalités :

  • Filtres dans les en-têtes de colonnes
  • Une ligne de filtre complète en haut du DataGrid
  • Affichage puissant des données hiérarchiques. Certains DataGrids tiers fonctionnent vraiment comme un puissant TreeView avec des DataGrids imbriqués. Bien que le WPF DataGrid permette de créer quelque chose comme ça, il ne le prend pas en charge immédiatement
  • Prise en charge de différents types de données. Comme par exemple une colonne DateTime. Dans le DataGrid de WPF, vous devez utiliser le DataGridTemplateColumn

Mais de toute façon, quoi que vous fassiez, je pense que la construction d'un DataGrid est une déclaration puissante et un engagement envers WinUI 3.0. Pour les applications LOB, vous ne pouvez pas prendre au sérieux un framework d'interface utilisateur qui ne contient pas de DataGrid intégré. Et c'est formidable de voir cet investissement réalisé pour WinUI !

@thomasclaudiushuber

Pour les applications LOB, vous ne pouvez pas prendre au sérieux un framework d'interface utilisateur qui ne contient pas de DataGrid intégré. Et c'est formidable de voir cet investissement réalisé pour WinUI !

D'accord! Dans notre cas, DataGrid est un composant essentiel que nous utilisons à plusieurs endroits et sans lequel nous ne pouvons vivre.

Affichage puissant des données hiérarchiques. Certains DataGrids tiers fonctionnent vraiment comme un puissant TreeView avec des DataGrids imbriqués.

Je suis déchiré sur ce sujet parce que, comme vous, je trouverais un DataGrid hiérarchique utile dans certaines situations, mais mon souci est que si DataGrid implémente une fonctionnalité hiérarchique, cela pourrait devenir excessivement complexe et difficile, et la publication de DataGrid serait très probablement considérablement retardé. De nouvelles fonctionnalités seraient difficiles à ajouter en raison de la complexité de rendre les nouvelles fonctionnalités compatibles à la fois avec les fonctionnalités hiérarchiques et non hiérarchiques.

Pour éliminer le problème de complexité/délai susmentionné, je suggère cette solution : Créez une classe distincte nommée HierarchicalDataGrid qui utilise/encapsule en interne une instance de DataGrid . Alternativement, HierarchicalDataGrid pourrait hériter publiquement de DataGrid mais je soupçonne que cet héritage est peu pratique, donc je préfère suggérer que HierarchicalDataGrid hérite de Control et ait en interne un champ privé de tapez DataGrid . Ainsi, la fonctionnalité hiérarchique serait implémentée dans la couche HierarchicalDataGrid qui dirige une instance interne non hiérarchique DataGrid .

Le principal avantage de la solution ci-dessus est qu'elle fournirait les fonctionnalités hiérarchiques souhaitées _sans_ enliser DataGrid , sans rendre DataGrid si complexe qu'il devienne ingérable et lent à développer.

Prise en charge de différents types de données. Comme par exemple une colonne DateTime.

Je suis d'accord. Découvrez les DataGridDateTimeColumn et DataGridTimeSpanColumn que j'ai proposés dans un message précédent.

@Pinox

Filtrez facilement toute la page

@thomasclaudiushuber

Filtres dans les en-têtes de colonnes ; Une ligne de filtre complète en haut du DataGrid ;

Les filtres seraient parfaits pour aider les utilisateurs finaux à trouver rapidement une ou plusieurs lignes, au lieu d'être obligés de rechercher manuellement un grand nombre de lignes pour trouver ce qu'ils recherchent.

Mais qu'en est-il du problème de faire correspondre le texte du filtre de l'utilisateur avec des colonnes non textuelles ? Signification des colonnes autres que DataGridTextColumn , telles que le filtrage avec DataGridTemplateColumn etc. ? Je suggère de résoudre ce problème avec quelque chose à peu près comme la solution suivante qui donne à DataGridColumn (et sous-classes) la possibilité de convertir une valeur de cellule en mots-clés à utiliser avec la recherche/filtrage/correspondance.

public delegate void DataGridCellValueToKeywordsConverter(object cellValue, ICollection<string> outputKeywords);

public class DataGridColumn
{
    ...
    public DataGridCellValueToKeywordsConverter CellValueToKeywordsConverter { get; set; }

    /// <param name="cellValue">The input/source value of the cell, to be converted to keywords.</param>
    /// <param name="outputKeywords">A collection that the method will add the keywords to.  The method invokes ICollection.Add for each keyword.</param>
    public virtual void ConvertCellValueToKeywords(object cellValue, ICollection<string> outputKeywords)
    {
        // Subclasses can override this method.  The default behavior is to invoke the delegate to do the job.
        DataGridCellValueToKeywordsConverter d = this.CellValueToKeywordsConverter;
        if (!(d is null)) d(cellValue, outputKeywords);
    }
}

Voici un exemple d'utilisation de la méthode ConvertCellValueToKeywords :

void TestKeywords(DataGridColumn column)
{
    var keywords = new System.Collections.Generic.HashSet<string>();
    foreach (object cellValue in someCellValueList)
    {
        keywords.Clear();
        column.ConvertCellValueToKeywords(cellValue, keywords);
        CheckIfFilterTextMatchesAnyKeyword(keywords);
    }
}

Alternativement, la valeur de la cellule pourrait être convertie en une seule chaîne au lieu d'une collection de mots-clés, mais la raison pour laquelle j'ai suggéré une collection de mots-clés est que les mots-clés permettent d'utiliser des algorithmes de recherche qui s'exécutent à grande vitesse même lorsque la quantité de lignes est très grand.

Copie facile depuis excel
Maintenant, il n'y a aucun moyen d'utiliser ctrl + v pour copier le contenu des cellules Excel dans la grille de données. Maintenant, il copie tout le contenu des cellules dans une cellule de la grille de données.

Veuillez fournir une prise en charge appropriée de plusieurs éléments sélectionnés, en faisant de SelectedItems une propriété de dépendance pour permettre l'utilisation de la liaison de données lors de la gestion des lignes sélectionnées.

@verelpode Je peux voir que la sélection de cellules individuelles est utile pour n'importe quelle application de type tableur, non ? Je pense que cela compte plus dans les scénarios d'édition que dans les scénarios d'affichage. Lors de l'affichage des données dans une grille de données sans modification, je conviens que je ne verrais pas l'utilité de la sélection de cellules individuelles et que j'aurais toujours une sélection de lignes complète.

@anawishnoff Je pense que @Laz3rPanth3r serait d'accord et les quelques problèmes ici et ici de la boîte à outils qui permettent d'ingérer des données facilement et simplement dans le DataGrid est une fonctionnalité importante. Vous devriez pouvoir amorcer la grille en vous liant à une collection d'objets ou d'objets expando dans une liste. S'il peut sélectionner intelligemment des colonnes pour les nombres, les chaînes et les types de données de base, ce serait formidable. Le développeur peut toujours faire plus de travail après pour personnaliser les colonnes individuelles au-delà de cela.

Je peux voir que la sélection de cellules individuelles est utile pour n'importe quelle application de type tableur, non ?

Dans une feuille de calcul, les en-têtes de colonnes sont nommés avec des lettres ascendantes de l'alphabet, A, B, C, D, … et le type de chaque colonne est le même, comme si chaque colonne utilisait DataGridTextColumn et aucune autre colonne type est nécessaire, et les noms de colonnes ne sont pas vraiment nécessaires non plus car ils sont générés automatiquement à partir de l'alphabet.
Une autre différence entre DataGrid et une feuille de calcul est qu'une feuille de calcul ne trie pas les lignes lorsque vous cliquez sur l'un des en-têtes de colonne.

Ce que je veux dire, c'est qu'il n'existe qu'une similitude superficielle (principalement une similitude visuelle) entre DataGrid et une feuille de calcul. DataGrid ne fonctionne pas vraiment comme une feuille de calcul. La technique de récupération des données cellulaires de DataGrid est également mal adaptée à un tableur.

J'adore DataGrid mais cela fonctionnerait mal si j'essayais de l'utiliser pour implémenter une feuille de calcul. Je ne pense pas que DataGrid soit le bon choix pour quiconque souhaite implémenter une feuille de calcul.

La conception existante de DataGrid s'aligne bien mieux avec une base de données SQL qu'une feuille de calcul, et les développeurs de bases de données SQL crieraient fort si quelqu'un essayait de prétendre qu'une base de données n'est « qu'une feuille de calcul ».

@verelpode Vos contributions sont si détaillées et réfléchies, merci beaucoup pour tout cela ! Je veux parler de l'idée de lier une source de données/la propriété ItemsSource de DataGrid, comme vous l'avez mentionné et @michael-hawker l'a également fait.

Actuellement, DataGrid oblige les applications à définir DataGrid.ItemsSource, mais il est peu pratique de créer un objet de liste contenant un million d'éléments. Ainsi, je souhaite que DataGrid cesse d'être intelligent dans le département de récupération de données et me laisse plutôt effectuer la récupération de données par moi-même, sans utiliser DataGridBoundColumn.Binding et DataGrid.ItemsSource.

C'est intéressant, et j'aimerais m'y intéresser davantage car nous sommes vraiment intéressés par la performance. Quel type de situation/scénario de données recherchez-vous en particulier ? Voudriez-vous connecter le DataGrid directement à un résultat de requête SQL, ou une base de données, ou quelque chose du genre ?

@khoshroomahdi Par copier-coller, voulez-vous dire que vous voudriez copier des cellules Excel dans un DataGrid dans une application en cours d'exécution et les remplir de cette manière ? C'est un cas d'utilisation intéressant, j'aimerais en savoir plus.

@alexyak , pourriez-vous développer un peu plus loin? La propriété SelectedItems vous permet actuellement d'obtenir tous les éléments sélectionnés dans un DataGrid (via le mode de sélection étendu cependant, pas précisément le mode de sélection multiple). Je vois d'après quelques autres commentaires ici que la sélection dans un DataGrid a définitivement besoin de travail, mais je veux mieux comprendre votre demande.

@anawishnoff oui exactement.
J'ai des données dans des cellules Excel et je souhaite les copier dans l'application en cours d'exécution.

Pour les scénarios non liés aux données, nous devrions examiner comment le contrôle WinForms DataGridView, que j'ai écrit il y a de nombreuses années, prenait en charge un mode virtuel : https://docs.microsoft.com/en-us/dotnet/api/system. windows.forms.datagridview.virtualmode

Actuellement, DataGrid oblige les applications à définir DataGrid.ItemsSource, mais il est peu pratique de créer un objet de liste contenant un million d'éléments. Ainsi, je souhaite que DataGrid cesse d'être intelligent dans le département de récupération de données et me laisse plutôt effectuer la récupération de données par moi-même, sans utiliser DataGridBoundColumn.Binding et DataGrid.ItemsSource.

Je suis d'accord que ce serait bien aussi. Je pense à quelque chose comme ListBox où vous pouvez soit ajouter des éléments manuellement, soit définir la ItemsSource. Cela dit, dans le passé, je générais simplement un nouveau DataTable représentant une vue partielle de la base de données complète pour implémenter la pagination (ce qui est un bon cas d'utilisation pour cela). Une vue de ce DataTable peut ensuite être définie sur ItemsSource. Donc, même si je pense vraiment que c'est agréable d'avoir, cela ne semble pas obligatoire pour de hautes performances.

En ce qui concerne tous les commentaires transformant le contrôle en plus ou moins un sous-ensemble d'Excel(r), je pense que le DataGrid devrait prendre en charge la sélection de cellules et l'édition par cellule. Cependant, des choses comme le copier/coller entre des applications externes doivent être gérées par le développeur.

@alexyak Concernant votre demande de faire de SelectedItems une DependencyProperty réelle et pouvant être Voir la discussion ici

@anawishnoff a écrit :

Vos contributions sont si détaillées et réfléchies, merci beaucoup pour tout cela !

Merci, je suis heureux d'apprendre que mes contributions sont utiles pour améliorer encore DataGrid :)

Quel type de situation/scénario de données recherchez-vous en particulier ? Voudriez-vous connecter le DataGrid directement à un résultat de requête SQL, ou une base de données, ou quelque chose du genre ?

C'est encore trop intelligent. Ce comportement intelligent empêche différentes applications d'effectuer la récupération de données de différentes manières. Différentes applications ont des circonstances très différentes, donc le "meilleur" système de récupération de données est différent pour différentes applications - il n'existe pas de "meilleur" unique. Par exemple, certaines applications n'affichent jamais plus de quelques centaines de lignes, alors que d'autres applications peuvent fonctionner avec un million de lignes comme @dotMorten mentionné, donc une seule taille de chaussure ne convient pas à tous.

Je suggère vraiment de le réduire à ce niveau :

  1. DataGrid décide qu'il doit afficher (ou utiliser d'une autre manière) la valeur qui existe dans la colonne 5 de la ligne 9001 dans le système de stockage de données externe.
  2. DataGrid informe l'application qu'elle a besoin de la valeur de la colonne 5 de la ligne 9001.
  3. L'application récupère la valeur de la colonne 5 de la ligne 9001. Cela peut impliquer une requête SQL asynchrone, une tâche C# asynchrone ou tout autre système de données. Idéalement, DataGrid devrait permettre à cette étape d'être asynchrone.
  4. L'application informe DataGrid qu'elle a fini de récupérer la valeur de la colonne 5 de la ligne 9001. L'application donne cette valeur à DataGrid.
  5. DataGrid utilise la valeur de la manière dont il a besoin, par exemple en affichant la valeur comme mentionné à l'étape 1.

@RBrid a écrit :

Pour les scénarios non liés aux données, nous devrions examiner comment le contrôle WinForms DataGridView, que j'ai écrit il y a de nombreuses années, prenait en charge un mode virtuel :

Oui oui oui! Je n'ai jamais utilisé WinForms DataGridView, mais je viens de lire la documentation maintenant et je pense que vous avez mis le doigt sur la tête. La page Web à laquelle vous avez lié dit :
_"Le mode virtuel est conçu pour être utilisé avec de très grands magasins de données."_

Je vois que le WinForms DataGridViewCellValueEventArgs contient ces propriétés :

public int RowIndex { get; }      // DataGrid sets RowIndex.
public int ColumnIndex { get; }   // DataGrid sets ColumnIndex.
public object Value { get; set; } // The app sets Value.

C'est excellent, sauf qu'idéalement, il devrait être mis à jour pour prendre en charge les mots-clés modernes C# async et await , ou l'équivalent UWP ( IAsyncOperation<TResult> ), ou plutôt tout type de délai entre DataGrid demandant la valeur de la cellule et l'application fournissant la valeur de la cellule à DataGrid. Ainsi, pour le mettre à jour afin de prendre en charge l'async, procédez comme suit :

  1. Conservez l'événement CellValueNeeded .
  2. Supprimez la propriété DataGridViewCellValueEventArgs.Value .
  3. Créez une méthode dans DataGrid nommée quelque chose comme SupplyCellValue que l'application invoquera, au lieu d'être obligée de définir immédiatement/de manière synchrone la propriété DataGridViewCellValueEventArgs.Value .

La méthode SupplyCellValue peut être définie comme ceci :

class DataGrid
{
    public void SupplyCellValue(int rowIndex, int columnIndex, object value);
    // Alternatively:
    public void SupplyCellValue(int rowIndex, DataGridColumn column, object value);
}

Ainsi à l'exécution la procédure est :

  1. DataGrid décide qu'il doit afficher (ou utiliser d'une autre manière) la valeur qui existe dans la colonne 5 de la ligne 9001 dans le système de stockage de données externe.
  2. DataGrid déclenche l'événement CellValueNeeded et définit DataGridViewCellValueEventArgs.RowIndex sur 9001 et DataGridViewCellValueEventArgs.ColumnIndex sur 5.
  3. Le gestionnaire d'événements (l'application) commence à exécuter une tâche asynchrone qui récupérera la valeur de la colonne 5 de la ligne 9001.
  4. Lorsque la tâche asynchrone se termine, c'est-à-dire lorsque l'application a récupéré la valeur, l'application appelle la méthode DataGrid.SupplyCellValue .

Cette technique simplifiée est plus puissante et flexible que la technique automatisée intelligente de DataGridBoundColumn.Binding et DataGrid.ItemsSource .

@alexyak , pourriez-vous développer un peu plus loin? La propriété SelectedItems vous permet actuellement d'obtenir tous les éléments sélectionnés dans un DataGrid (via le mode de sélection étendu cependant, pas précisément le mode de sélection multiple). Je vois d'après quelques autres commentaires ici que la sélection dans un DataGrid a définitivement besoin de travail, mais je veux mieux comprendre votre demande.

Nous avons besoin d'une liaison de données bidirectionnelle appropriée pour que les modèles de vue puissent gérer plusieurs sélections

@verelpode , nous avions modélisé le modèle WinForms DataGridView d'après les contrôles Win32 ComCtl32 encore plus anciens. En particulier, je pense à la façon dont le contrôle d'affichage de liste a utilisé le message LVN_GETDISPINFO en mode virtuel (voir https://docs.microsoft.com/en-us/windows/win32/controls/list-view-controls-overview #handling-virtual-list-view-control-notification-codes et https://docs.microsoft.com/en-us/windows/win32/controls/lvn-getdispinfo). Vieux trucs des années 90.

Quoi qu'il en soit, je pense que la manière dont l'aspect de récupération de données asynchrone doit être géré passe par des « événements différés ».
Les contrôles WinUI utilisent déjà deux fois les événements différés :

runtimeclass RefreshRequestedEventArgs
{
    Windows.Foundation.Deferral GetDeferral();
}

runtimeclass TeachingTipClosingEventArgs
{
    TeachingTipCloseReason Reason{ get; };
    Boolean Cancel;
    Windows.Foundation.Deferral GetDeferral();
}

C'est le modèle que le nouvel événement CellValueNeeded de DataGrid voudrait adopter. Il permet au gestionnaire d'événements de fournir des données de manière asynchrone et d'indiquer au contrôle quand il a terminé. Voir https://docs.microsoft.com/en-us/uwp/api/windows.foundation.deferral.

@RBrid
Bon point sur le fait que GetDeferral() soit le nouveau modèle standard. Dans ce cas particulier de CellValueNeeded , il semble beaucoup plus difficile d'utiliser Deferral que dans d'autres cas/événements. Corrigez-moi si je me trompe, mais je pense que le problème avec l'utilisation de GetDeferral() dans ce cas particulier est que GetDeferral() crée un nouvel objet à chaque fois qu'il est invoqué, ce qui conduirait à un une énorme quantité de création et de nettoyage d'objets étant répétée pour chaque cellule de chaque ligne d'un nombre potentiellement élevé de lignes. Je n'ai pas vu le code source de diverses implémentations de GetDeferral() donc je peux me tromper à ce sujet.

En d'autres termes, à moins que Deferral supporte le recyclage ou ait un moyen de rendre GetDeferral() beaucoup plus efficace, alors c'est toujours trop intelligent. Ma proposition simplifiée avec la méthode SupplyCellValue évite les frais généraux liés à la création, à l'achèvement et à la suppression d'une nouvelle instance Deferral pour chaque cellule de chaque ligne applicable.

  1. GetDeferral()
  2. Report.Terminé
  3. Report.Éliminer
  4. Répétez les étapes ci-dessus un grand nombre de fois.

La tâche de récupération d'une valeur de cellule n'est pas la seule tâche de gestion des données qui peut être sous-traitée à l'application. Le tri peut également être sous-traité. Par conséquent, il pourrait être intéressant d'envisager une interface plutôt qu'un événement unique CellValueNeeded . Une application donnerait à DataGrid un module de gestion de données sous la forme d'un objet qui implémente une certaine interface. DataGrid invoquerait cette interface afin de récupérer les valeurs des cellules, mais aussi potentiellement d'autres tâches telles que le tri.

Pour prendre en charge le million de lignes mentionnées par @dotMorten , CellValueNeeded seul ne résoudrait pas l'autre problème qui se produit lorsque l'utilisateur clique sur un en-tête de colonne et que le DataGrid essaie de trier un million de lignes. Ainsi, la récupération ET le tri des cellules pourraient être sous-traités à l'application via le module/l'interface susmentionnés.

Si l'application ne fournit aucun module/objet de gestion de données à DataGrid, alors idéalement, DataGrid utiliserait un module de gestion de données par défaut. Ainsi, tout le code de liaison de données existant dans DataGrid serait déplacé hors de DataGrid et dans une nouvelle classe distincte - la classe qui implémente le module de gestion de données par défaut en travaillant avec DataGridBoundColumn.Binding etc.

c'est-à-dire que lorsque le tri est également sous-traité à l'application ou à son module de gestion de données, cela ouvre la porte à diverses solutions prenant en charge un million de lignes, telles que l'écriture d'un module de gestion de données qui demande au serveur SQL d'effectuer le tri, au lieu d'essayer- et-ne pas effectuer le tri d'un million de lignes dans DataGrid en moins de 10 ou 20 heures après que l'utilisateur a cliqué sur l'en-tête de colonne pour commencer le tri.

@verelpode , oui c'est une préoccupation valable. Je m'attendrais à ce que le DataGrid possède un pool d'objets Windows.Foundation.Deferral recyclables. Nous aurions besoin de confirmer la faisabilité et les performances à coup sûr.

Ayant pris une dépendance sur le Windows Community Toolkit DataGrid qui a Row Details comme fonctionnalité (bien qu'avec un bug de performances sérieux mais avec une solution de contournement), nous aimerions vraiment que cette nouvelle grille de données l'ait également comme fonctionnalité - avec la même option pour avoir plusieurs détails de ligne simultanément. L'utiliser pour un scénario de flux de données de serveur à client.

Concernant un million de lignes par rapport à une interface graphique de pagination , @robloo a écrit :

Je suis d'accord que [supporter un million de lignes] serait également bien. .... Cela dit, dans le passé, je générais simplement un nouveau DataTable représentant une vue partielle de la base de données complète pour implémenter la pagination (ce qui est un bon cas d'utilisation pour cela). Une vue de ce DataTable peut ensuite être définie sur ItemsSource. Donc, même si je pense vraiment que c'est agréable d'avoir, cela ne semble pas obligatoire pour de hautes performances.

La pagination est une technique utile et mérite d'être mentionnée, mais elle présente des inconvénients substantiels : elle rend la fonction de tri de DataGrid pratiquement inutile. De même pour une fonctionnalité de filtrage dans la prochaine version de DataGrid. La pagination rend le tri et le filtrage inutiles ou du moins beaucoup moins utiles.

Par exemple, imaginez que 2 ou 3 colonnes sont des colonnes de date et que l'utilisateur souhaite afficher les lignes qui ont la date la plus récente (ou la plus ancienne) dans la deuxième colonne de date. Ainsi, l'utilisateur clique sur le deuxième en-tête de colonne de date pour trier le DataGrid par cette colonne, et clique également pour changer le sens de tri de décroissant à croissant ou vice-versa. Cela fonctionne très bien si aucune pagination n'est en cours d'utilisation ou si la quantité totale de lignes est suffisamment petite pour ne pas dépasser une seule page, mais elle s'interrompt s'il existe plusieurs pages.

L'utilisateur doit trouver la date la plus récente (ou la plus ancienne) sur toutes les lignes, mais une interface graphique DataGrid paginée n'affiche que la date la plus récente (ou la plus ancienne) dans la page actuelle, pas sur toutes les lignes, ainsi la pagination rend le tri (et le filtrage) pratiquement inutile.

Cela soulève la question de savoir quelles lignes aboutissent à quelle page. La réponse est que chaque page contient généralement un sous-ensemble pratiquement aléatoire de lignes, lorsque les pages/lignes sont obtenues via une requête SQL SELECT qui n'utilise pas ORDER BY . (Je veux dire aléatoire du point de vue de l'utilisateur, pas vraiment aléatoire.)

Le pseudo-aléatoire n'est pas utile pour les utilisateurs finaux. Pour éliminer ce caractère aléatoire problématique, nous pourrions penser à utiliser SQL ORDER BY (avec le mot-clé ASC ou DESC pour contrôler le sens du tri), puis oui les pages sont non plus aléatoire, mais il est toujours cassé car cette utilisation de ORDER BY trie toujours par la même colonne et le même sens de tri, ce qui signifie que l'ordre de tri est souvent différent de l'ordre de tri choisi par l'utilisateur final cliquant sur une colonne en-tête dans DataGrid.

Pour résoudre ce problème, vous devrez utiliser une requête SQL différente chaque fois que l'utilisateur clique sur un en-tête de colonne différent. Le SQL ORDER BY ... ASC/DESC devrait être conservé le même que l'ordre de tri choisi par l'utilisateur final de DataGrid. DataGrid ne prend pas en charge cela actuellement.

Une solution suggérée est dans mon message précédent : j'ai suggéré que DataGrid permette d'externaliser le tri vers l'application (ou vers un "module de gestion des données"). Cette idée permettrait à l'application (ou "module de gestion de données") de modifier le SQL ORDER BY ... ASC/DESC chaque fois que l'utilisateur final modifie l'ordre de tri de DataGrid en cliquant sur les en-têtes de colonne, etc.

Il peut également être intéressant de donner à l'événement préexistant DataGrid.Sorting une propriété réglable dans les arguments de l'événement qui permet aux applications (le gestionnaire d'événements) d' annuler le tri et de prendre le relais. Idéalement, les arguments de l'événement spécifieraient également si le changement d'ordre de tri a été demandé par programme par rapport à celui demandé par l'utilisateur final en cliquant sur les en-têtes de colonne, etc. Dans ce cas, il peut également être utile de renommer l'événement DataGrid.Sorting en quelque chose de moins ambigu car actuellement l'intention et le but de l'événement Sorting ne sont pas clairs. Voir aussi l' événement proposé

Ayant pris une dépendance sur le Windows Community Toolkit DataGrid qui a Row
Détails en tant que fonctionnalité (bien qu'avec un bug de performances sérieux mais avec une solution de contournement), nous aimerions
J'aime vraiment cette nouvelle grille de données pour avoir cela aussi comme fonctionnalité - avec la même option pour avoir
détails de plusieurs lignes simultanément. L'utiliser pour un scénario de flux de données de serveur à client.

Lien vers le problème de performances Row Details : https://github.com/windows-toolkit/WindowsCommunityToolkit/issues/2842
Repro : https://github.com/observito/DataGridRowDetailsPerfTest

Un bon point de départ est de regarder votre partenaire Telerik avec son RadDataGrid (UWP Open Source). Avec un de mes clients, je l'ai utilisé et ça marche vraiment bien. Il est hyper rapide et polyvalent. La seule chose qui est difficile est leur code, il n'y a aucun moyen de modifier quoi que ce soit de leur moteur sans une bonne compréhension de l'architecture.

Je m'attendrais à ce que le nouveau DataGrid soit aussi performant que Telerik.

Les fonctionnalités de la grille de synchronisation sont excellentes, mais elles ne sont pas compatibles avec mvvm. Vous pourriez donc faire mieux.

Hé encore tous ! Continuons cette conversation. Que pensez-vous de la documentation DataGrid qui existe actuellement ?

Voici un lien vers la page de documentation principale qui renvoie à toutes les autres pages pertinentes.

Si nous créons un nouveau DataGrid, nous voulons nous assurer que la documentation qui l'accompagne sera de premier ordre, facile à comprendre et aborde tous les problèmes et scénarios qui sont importants pour nos développeurs.

_Quels sont les sujets que vous souhaiteriez que nous ayons ? Quels sont les sujets qui pourraient être clarifiés ?_

Hé encore tous ! Continuons cette conversation. Que pensez-vous de la documentation DataGrid qui existe actuellement ?

Voici un lien vers la page de documentation principale qui renvoie à toutes les autres pages pertinentes.

Si nous créons un nouveau DataGrid, nous voulons nous assurer que la documentation qui l'accompagne sera de premier ordre, facile à comprendre et aborde tous les problèmes et scénarios qui sont importants pour nos développeurs.

_Quels sont les sujets que vous souhaiteriez que nous ayons ? Quels sont les sujets qui pourraient être clarifiés ?_

Des images montrant des configurations DataGrid typiques, ainsi que le xaml et le code pour les créer, seraient utiles.

Des images montrant des configurations DataGrid typiques, ainsi que le xaml et le code pour les créer, seraient utiles.

@mdtauk Existe-t-il des configurations DataGrid spécifiques que vous trouvez "typiques", ou des cas d'utilisation dans lesquels vous trouvez systématiquement que DataGrid est le meilleur choix à utiliser ?

Des images montrant des configurations DataGrid typiques, ainsi que le xaml et le code pour les créer, seraient utiles.

@mdtauk Existe-t-il des configurations DataGrid spécifiques que vous trouvez "typiques", ou des cas d'utilisation dans lesquels vous trouvez systématiquement que DataGrid est le meilleur choix à utiliser ?

Je pense que pour la période WinUI 3.0, montrant les scénarios communs de vue WPF, Win32 grille de données/icône. Ainsi que ce que Microsoft considère comme les conceptions d'interface utilisateur Fluent/Modern DataGrid.

C'est si l'idée derrière le contrôle est d'encourager le passage des anciennes interfaces utilisateur à WinUI 3

@anawishnoff Je pense que certaines des questions que nous avions de la boîte à outils en termes de choses que les gens recherchaient de la documentation sur où plus de ces scénarios également:

  • Thématisation/Re-modèle/Alignement
  • Liaison de données (en général et en XAML)
  • Gestion des événements/sélections/boîtier
  • Comportements d'édition (en particulier éditer au clic)
  • Multi-pagination (qui devrait bien se marier avec #60 et #268)

    • Chargement de la coordination de l'animation pendant le chargement des données

  • Copier/Coller/Formatage
  • Différents types de données de colonne (et personnalisés) (par exemple, énumérations)
  • Menus contextuels
  • Accessibilité

J'ai remarqué que le Toolkit DataGrid existant nécessite un IEnumerable pour sa propriété ItemsSource. Bien que cela semble être une décision logique, cela rend impossible la définition de l'objet renvoyé par Windows.Storage.BulkAccess.FileInformationFactory.GetVirtualizedItemsVector() comme cette propriété. (Sauf s'il existe un moyen de convertir l'objet renvoyé) En outre, d'autres contrôles tels que ListView et GridView prennent en charge la définition de leur propriété ItemsSource sur une valeur du type d'objet. Je n'en suis pas certain, mais cette prise en charge permettrait probablement une interface utilisateur plus réactive pendant les opérations de stockage.

@mdtauk Existe-t-il des configurations DataGrid spécifiques que vous trouvez "typiques", ou des cas d'utilisation dans lesquels vous trouvez systématiquement que DataGrid est le meilleur choix à utiliser ?

Je pense que pour la période WinUI 3.0, montrant les scénarios communs de vue WPF, Win32 grille de données/icône. Ainsi que ce que Microsoft considère comme les conceptions d'interface utilisateur Fluent/Modern DataGrid.

C'est si l'idée derrière le contrôle est d'encourager le passage des anciennes interfaces utilisateur à WinUI 3

Exemple Win32 (Explorateur de fichiers)
image

Exemple WPF
image

Exemple de tissu Web
image

exemple UWP
image

@mdtauk Merci pour ces captures d'écran ! Je pense vraiment qu'il est important de mettre en évidence les éléments clés qui ont fonctionné dans les versions précédentes du contrôle et de documenter comment ils peuvent être atteints avec le nouveau contrôle.

@michael-hawker Génial. Je vois déjà quelques sujets qui ont été soulevés plusieurs fois sur ce fil, donc c'est certainement un bon point de départ.

@ duke7553 Je ne suis pas sûr à 100% d'une solution à cela, ou si la prise en charge d'un type d'objet serait sage. Peut-être que @RBrid peut intervenir ?

@anawishnoff & @duke7553 , je construirais le nouveau contrôle DataGrid au-dessus du nouveau contrôle WinUI ItemsRepeater. Et ce contrôle expose son ItemsSource en tant qu'objet :
Object ItemsSource { get; set; };

J'espère qu'il prend en charge CellDecorationStyleSelector comme dans Telerik.

@anawishnoff

nous souhaitons le faire passer à un contrôle natif WinUI

hmmmm quand vous dites « obtenir un diplôme », cela inclurait-il de le rétrograder en C++ ? Actuellement, le DataGrid de WinUI est écrit en C#. J'espère que « diplômé » ne signifiera pas « rétrogradation ». Surtout, WinUI doit atteindre un point où l'équipe WinUI peut dire que WinUI est meilleur que WPF dans tous les domaines qui comptent, mais cet objectif est terriblement en retard. Cet objectif deviendra encore plus en retard si du temps/des ressources sont gaspillés dans des rétrogradations inutiles de code telles que DataGrid de C# à C++.

Bien qu'il existait à l'origine une raison d'écrire WinRT/UWP/WinUI en C++, cette raison n'a malheureusement pas abouti, et Google/Android a pris la plupart des parts de marché des smartphones, donc la raison originale d'utiliser C++ n'est plus applicable (facilement dit avec le recul, mais pas si facile à dire plus tôt). Si WinUI était écrit en C# depuis le début, alors l'objectif meilleur que WPF aurait été atteint il y a 3 ans, mais maintenant il y a 8 ans et il n'est toujours pas atteint, et personne n'est en mesure de dire avec précision quand l'objectif sera atteint. Espérons que l'objectif meilleur que WPF et les objectifs de « graduation » de WinUI DataGrid ne seront pas retardés par une conversion inutile vers un langage de programmation plus ancien et moins productif.

Je suis en faveur du C++ parce que j'ai commencé à programmer en C++ avant même que le C# n'existe, et les gens préfèrent s'en tenir à ce qu'ils ont appris à l'origine et se souviennent avec émotion du "bon vieux temps"_. Malgré mon parti pris en faveur du C++, j'ai arrêté d'écrire du C++ et je pense que DataGrid ne devrait pas être rétrogradé en C++ et retardé. Laissez-le en C# et concentrez-vous sur des choses plus importantes, comme apporter les diverses améliorations suggérées par les personnes dans ce numéro et atteindre l'objectif meilleur que WPF avant que 1 décennie ne soit atteinte.

J'aime de nombreux aspects de WinUI, j'apprécie ses nombreuses améliorations intelligentes et j'écris du code d'application pour WinUI, mais voulez-vous connaître la vérité honnête ? La vérité est que, malheureusement, je n'ai encore jamais publié d' application WinUI pour les utilisateurs. Le logiciel mis à la disposition des utilisateurs est écrit avec WPF, et les utilisateurs s'en moquent car le logiciel fonctionne bien et inclut des modernisations de l'interface graphique. Bien que j'aie écrit tout un tas de code d'application pour WinUI, il s'agit de préparation, de planification, de test, d'attente, pas réellement utilisé par les utilisateurs. Espérons que l'année prochaine, le premier composant WinUI sera disponible pour les utilisateurs, mais j'apprécierai ce basculement beaucoup plus qu'eux. Les utilisateurs remarqueront à peine le basculement, si tout se passe comme prévu.

Du point de vue de Microsoft, WinRT/UWP est un logiciel de qualité, publié aux utilisateurs depuis l'année 2012, mais de mon point de vue, UWP est toujours une grande expérience. Pour moi, UWP (y compris WinUI) est une grosse version de test bêta avec laquelle je joue depuis des années.

Pendant les premières années d'UWP, chaque année je pensais : _"euh... j'attendrai l'année prochaine. Il y a encore trop de choses dans WPF qui manquent à UWP. L'année prochaine sera sûrement meilleure."_
Puis l'année suivante est arrivée et j'ai répété la même pensée. Puis l'année suivante est arrivée et j'ai répété la même pensée. Espérons que cette année soit la dernière année à le dire, ou du moins c'est mon intention.

WinUI ne peut pas se permettre plus de retards. Laissez le DataGrid de WinUI en tant que code C#. Commencez à écrire plus de code WinUI en C# afin d'augmenter la productivité. Cela fait maintenant 8 ans et Android a pris des parts de marché massives. C'est une situation grave.

Au fait, j'étais en fait gentil/généreux quand j'ai dit que UWP est toujours une version bêta, car techniquement, UWP correspond à la définition d'une version alpha, pas bêta. Pour être une vraie version bêta, elle doit être complète, mais UWP n'a pas encore atteint le statut de fonctionnalité complète, donc UWP est toujours alpha. Par exemple, l'article de Wikipédia sur le « Cycle de vie des versions logicielles » dit :

« La phase bêta commence généralement lorsque le logiciel est complet, mais contient probablement un certain nombre de bogues connus ou inconnus. »
"Le logiciel Alpha peut ne pas contenir toutes les fonctionnalités prévues pour la version finale."

Wikipédia définit « fonctionnalité complète » comme suit :

« Une version complète des fonctionnalités d'un logiciel a toutes ses fonctionnalités prévues ou principales mises en œuvre, mais n'est pas encore définitive en raison de bugs, de problèmes de performances ou de stabilité. Cela se produit à la fin des tests alpha de développement. »

Il serait déraisonnable de décrire UWP comme complet car s'il est vraiment complet, alors UWP doit avoir toutes les capacités de Windows '95 et plus, mais ce n'est pas le cas -- UWP ne dépasse pas encore Windows 95 dans tous les domaines . Windows 95 est sorti il ​​y a 25 ans. Lorsque UWP/WinRT est sorti il ​​y a 7 à 8 ans, Microsoft a subi une perte de 900 millions de dollars et un manque criant d'applications dans le Windows Store. Il s'agissait d'une version alpha étiquetée comme version finale, les développeurs d'applications ont donc attendu et regardé. Aujourd'hui, près de 8 ans plus tard, c'est toujours une version alpha et très attendue, et j'attends et je regarde et j'attends toujours.

Il serait très bénéfique pour Microsoft et les développeurs si Microsoft prenait une décision/un engagement sérieux de donner la priorité à la production d'une véritable version bêta d'UWP, qui serait rapidement suivie d'une véritable version Release Candidate. Ce serait fortement recommandé et une ligne de conduite très sensée. Ce serait excellent pour tout le monde.

UWP est toujours alpha/incomplet pour plusieurs raisons, par exemple : il y a 25 ans, il était facile d'utiliser la fonction "MoveFile" dans Windows 95 pour déplacer un fichier ou un dossier (bien que la fonction s'appelait "MoveFile", elle prenait en charge les deux fichiers et dossiers). UWP peut-il déplacer des dossiers ? Non pas encore. De toute évidence, la possibilité de déplacer des dossiers est l'une des fonctionnalités essentielles de base, mais UWP manque toujours cette fonctionnalité essentielle et d'autres, il serait donc déraisonnable de décrire UWP comme une fonctionnalité complète, donc UWP n'a pas encore atteint le statut bêta, malgré sorti il ​​y a 7-8 ans. Microsoft doit donner la priorité à une véritable version bêta d'UWP.

Un référentiel GitHub public pour le suivi des problèmes UWP (autres que les problèmes d'interface utilisateur) n'existe pas encore, à ma connaissance (ou si un référentiel UWP existe, je ne l'ai pas trouvé). Encore une fois, cela correspond à la définition d'une version alpha car un repo public de suivi des problèmes est souvent indésirable pendant une étape alpha. S'il s'agissait d'une véritable version bêta ou publiée, un référentiel public de suivi des problèmes aurait déjà été ouvert et UWP inclurait toutes les fonctionnalités de Windows 95 et Windows 7, et plus encore.

Comment cette situation affecte-t-elle DataGrid ? Considérant qu'une version bêta complète d'UWP est tellement en retard, et compte tenu de la gravité de cette situation et de la perte de plusieurs milliards de dollars que Microsoft a subie en conséquence, il ne serait pas justifiable et raisonnable de perdre encore plus de temps en convertissant WinUI DataGrid en code non managé et en un ancien langage de programmation. Microsoft a répété à plusieurs reprises qu'un grand avantage de C# et du "code managé" est une productivité accrue, et je peux dire que les affirmations de Microsoft concernant le "code managé" étaient certainement vraies dans mes expériences avec C++ et C#. UWP aurait atteint le véritable statut bêta il y a plusieurs années s'il était principalement écrit à l'aide de code managé à partir de la version 1.0. J'espère donc que la situation ne sera pas encore pire en effectuant encore plus de ces rétrogradations inutiles du code managé au code non managé.

À titre de comparaison, la plupart de WPF a été achevé avec succès au cours des 4 années de 2006 à 2010. WPF est principalement du code managé, contrairement à UWP. UWP est un code non managé et après 8 ans de développement, Windows 95 bat encore UWP dans quelques domaines, donc Microsoft avait clairement raison lorsque Microsoft a affirmé que le code managé augmentait la productivité. Ce problème doit être résolu au plus vite. WinUI aurait dû être beaucoup plus facile/rapide à créer que WPF car les deux projets ont le même propriétaire (Microsoft), donc WinUI est librement autorisé à copier le code de WPF. Ainsi, WinUI aurait dû nécessiter environ la moitié du temps de développement de WPF. En fait, WinUI n'aurait jamais dû être démarré, Microsoft aurait plutôt dû développer les fonctionnalités de WinUI dans les nouvelles versions de WPF -- WinUI aurait dû être WPF 5.0. Donc, la situation était un gros gâchis et il serait très bénéfique pour Microsoft de donner la priorité au nettoyage restant de ce gâchis, et de cesser de faire des choses qui rendent l'erreur de plusieurs milliards de dollars encore pire qu'elle ne l'était déjà (et l'est toujours quand vous regardez à la situation actuelle des parts de marché des smartphones).

Cela signifie que, afin d'éviter encore plus de pertes, Microsoft gagnerait à se souvenir de ce que Microsoft a déjà dit/savait dans le passé :

  • Le code managé augmente la productivité, selon les propres affirmations de Microsoft. Lorsque vous comparez les 8 ans d'UWP aux 4 ans de WPF, la conclusion doit être que Microsoft avait raison concernant les avantages du code managé.
  • Les langages de script sont pour les scripts et les langages de programmation sont pour la programmation. JavaScript et PowerShell conviennent aux fins auxquelles ils sont destinés (scripts), mais ce sont évidemment des choix inappropriés pour la programmation d'applications.
  • Pour réussir, Microsoft doit passer de l'alpha à la bêta à la version, et cela ne réussit que s'il s'agit d'une véritable version, et non d'une alpha incomplète étiquetée "release". Ainsi, le Microsoft Store a été pour la plupart vide pendant une période excessivement longue.
  • Les ingénieurs logiciels et autres employés travaillent mieux lorsqu'ils travaillent en échange d'une rémunération et d'un nombre d'heures de travail raisonnables, ainsi que d'un environnement de travail sain. De toute évidence, la perte de plusieurs milliards de dollars de Microsoft ne sera jamais inversée par l'utilisation de fanatiques/zélotes non rémunérés et de leurs soi-disant « emplois de jour » et « emplois de nuit » et leurs conditions de travail insoutenables/malsaines.
  • L'énorme gain de parts de marché d'Android n'était pas dû à des fanatiques non rémunérés. Si des fanatiques non rémunérés étaient la raison de la victoire, alors Linux n'aurait pas échoué. L'explication est bien plus simple : le prix des tablettes et smartphones Android est BEAUCOUP inférieur à celui des tablettes et smartphones Windows. De toute évidence, les utilisateurs finaux ne se soucient pas des religions/idéologies « open source » (les utilisateurs ne savent même pas ce que c'est), mais ils aiment simplement les prix bas des appareils Android.
  • Win16 est extrêmement obsolète. C'est la technologie d'il y a 20-30 ans, des premiers jours de programmation du "Wild West". Par conséquent, arrêtez d'écrire un nouveau code basé sur Win16. L'appeler "Win32" ne change pas vraiment le fait qu'il s'agit toujours fondamentalement de Win16. Win32 est la même chose que Win16 sauf avec les pointeurs étendus en taille de 16 bits à 32 bits. Trop de groupes chez Microsoft continuent d'écrire du nouveau code basé sur Win16/32. C'est très inefficace et un gros gaspillage de ressources.

@anawishnoff

nous souhaitons le faire passer à un contrôle natif WinUI

Voir aussi l'article de Wikipédia "Coût irrécupérable" :

L'effet de coût irrécupérable (ou effet Concorde) est le fait que le comportement suit souvent le sophisme du coût irrécupérable ; les gens démontrent "une plus grande tendance à poursuivre un effort une fois qu'un investissement en argent, en efforts ou en temps a été fait." Ce comportement peut être décrit comme « jeter du bon argent après le mauvais », et refuser d'y succomber peut être décrit comme « réduire ses pertes ».

Et de même "Plan continuation bias" :

Le biais de continuation du plan, l'obtention du résultat ou la pression sur l'it est une tendance imprudente à persister avec un plan qui échoue. Il s'agit d'un danger dangereux pour les capitaines de navire ou les pilotes d'avion qui peuvent s'en tenir à un parcours planifié même si cela conduit à une catastrophe fatale et ils devraient plutôt abandonner. ..... Les projets souffrent souvent de dépassements de coûts et de retards en raison de l'erreur de planification et de facteurs connexes, notamment un optimisme excessif, une réticence à admettre l'échec, une pensée de groupe et une aversion pour la perte des coûts irrécupérables.

WinRT/UWP a fait subir à Microsoft une perte de 900 millions de dollars au cours de la première ou de la deuxième année, et un magasin d'applications vide pendant beaucoup trop longtemps. WinRT/UWP a été un échec catastrophique, il aurait donc dû être abandonné la deuxième année, mais il a été poursuivi en raison du "biais de continuation du plan" et de l'aversion pour la perte des coûts irrécupérables. Ce truc est enseigné dans les cours de gestion. La poursuite du plan a-t-elle finalement effacé ou inversé l'échec catastrophique de WinRT/UWP ? Non, c'est toujours un échec catastrophique aujourd'hui si vous regardez en termes de part de marché des smartphones. Ces descriptions dans Wikipedia décrivent avec précision la situation de l'UWP.

Aujourd'hui, nous devons tous convenir qu'à l'heure actuelle, 7 à 8 ans après la sortie de WinRT/UWP, il est maintenant trop tard pour annuler UWP, mais cela signifie que nous sommes à nouveau victimes du "biais de continuation du plan " et l'aversion pour la perte des coûts irrécupérables.

Alors, que peut-on raisonnablement faire pour sauver la situation ? Nous ne pouvons pas sauver la situation en annulant UWP, même s'il aurait certainement dû être annulé il y a des années. Ce que nous pouvons faire est ceci : Acceptez les dommages gigantesques qui ont été causés par WinRT, mais ne causez aucun autre dommage, et apportez des modifications aux procédures/politiques du projet. Cela signifie, arrêtez de répéter/continuer les mêmes erreurs catastrophiques de WinRT. Par exemple, arrêtez de rétrograder de telles quantités de code managé vers un ancien code « natif » non managé et improductif. Le délai pour atteindre le véritable statut bêta est déjà très important. Pourquoi aggraver le délai ?

L'erreur de « biais de continuation du plan »/coût irrécupérable continue si DataGrid est rétrogradé en code « natif » non géré. Lorsqu'une erreur catastrophique telle que WinRT/UWP est commise, cela devient bien pire lorsque cette même erreur est répétée encore et encore. Afin de limiter les dégâts, il faut arrêter de répéter la même erreur. Il est bel et bien temps d'apprendre de l'échec catastrophique de WinRT et de commencer à appliquer des bandages pour arrêter la perte de sang en cours.

Convertir DataGrid en code non managé revient à aller dans une bibliothèque et à emprunter tous les meilleurs livres de gestion de projet aux meilleurs auteurs avec le plus de connaissances/d'expérience, puis de jeter tous ces excellents livres de gestion dans un feu de joie et de les regarder brûler.

@verelpode Je suis curieux de savoir ce que vous en

@dotMorten -- la raison pour laquelle j'ai écrit des détails supplémentaires dans ces messages est que si je n'explique pas correctement le problème, les gens ne le comprendront pas. Mais malheureusement, maintenant, je vois que le détail supplémentaire a échoué et qu'il n'a toujours pas été compris de toute façon. C'est très frustrant. C'est la raison pour laquelle beaucoup de gens ne prennent même pas la peine d'écrire des commentaires, car ils pensent qu'il est inutile d'essayer d'expliquer ce genre de problèmes aux gens, et même si le message est bien compris, c'est dans la nature humaine de tirer sur le personne qui annonce la mauvaise nouvelle, alors mieux vaut ne rien dire du tout, ou simplement sourire « poliment » en pensant le contraire.

car il devient complètement indépendant de cela avec la v3.

Cette déliaison v3 n'empêche pas la répétition des mêmes erreurs. Le « biais de continuation du plan » existe toujours.

Accédez à la page d'accueil de Microsoft :
https://www.microsoft.com/en-us/
Faites maintenant défiler la page d'accueil jusqu'à ce que vous voyiez Windows Phone. Oh! Regarde ça! Nous avons atteint la fin de la page d'accueil et Windows Phone n'est mentionné PARTOUT sur la page d'accueil de Microsoft ! Qu'est-ce que ça veut dire? Cela signifie, réveillez-vous. Cela signifie que UWP a été un échec catastrophique comme je l'ai dit. Cela signifie qu'il est important d'arrêter de répéter les mêmes erreurs qui ont conduit à l'échec de l'UWP. Cela signifie, changer le plan afin de secourir et de se remettre de la catastrophe.
Ce serait une erreur de gestion si WinUI et DataGrid continuaient à répéter les mêmes erreurs que lors de l'échec d'UWP.

"En mai 2016, Microsoft a vidé son activité mobile, .... En 2017, le dirigeant de Microsoft Joe Belfiore a révélé que Microsoft avait cessé le développement de nouveaux téléphones Windows et de nouvelles fonctionnalités pour Windows 10 Mobile, citant les pertes de parts de marché et le manque de développement d'applications."
-- https://en.wikipedia.org/wiki/Microsoft_Mobile

Ana énumère 5 points pour fournir des commentaires sur wrt DataGrid. Lequel de ces points commentez-vous ? Je suppose que c'est le peu que je ne comprends pas de ce que vous écrivez. UWP ne satisfait pas les besoins de tout le monde, mais WinUI3 ne dicte pas l'utilisation du modèle d'application UWP, et vous semblez être principalement contre UWP ? Alors ça devrait aller là-bas.

Vous avez mentionné que DataGrid ne devrait pas continuer à faire les mêmes erreurs qu'il a faites. Alors, quelles sont ces erreurs spécifiquement par rapport au DataGrid existant, et comment suggérez-vous qu'elles soient corrigées ? (à part que vous ne voulez pas qu'il soit implémenté en C++ pour une raison quelconque)

@dotMorten

Ana énumère 5 points pour fournir des commentaires sur wrt DataGrid. Lequel de ces points commentez-vous ?

La partie où j'ai cité Ana au début de mon message. Je commente la partie du message d'Ana que j'ai citée au début de mon message.

WinUI3 ne dicte pas l'utilisation du modèle d'application UWP

Cela n'a rien à voir avec mon message. WinUI 3 étant non lié et disponible via le package nuget n'est pas pertinent pour la question de savoir si WinUI 3 continue les mêmes erreurs de gestion qui ont conduit à l'échec d'UWP et de Windows Phone et à la perte de plusieurs milliards de dollars de Microsoft.

comment suggérez-vous qu'ils devraient être corrigés?

Les 6 puces à la fin de mon message précédent . Le deuxième point (script) concerne WinUI et UWP en général, mais ne concerne pas DataGrid. La première puce est la plus importante si vous posez des questions spécifiquement sur DataGrid.
J'ai également écrit : arrêtez de rétrograder de si grandes quantités de code géré vers un ancien code "natif" non géré et non productif. Le délai pour atteindre le véritable statut bêta est déjà très important. Pourquoi aggraver le délai ?

@anawishnoff a écrit :

nous souhaitons le faire passer à un contrôle natif WinUI

« le passer à un contrôle natif de WinUI » constitue pratiquement une continuation/répétition de certaines des mêmes erreurs qui ont conduit aux « pertes de parts de marché et au manque de développement d'applications » mentionnés dans Wikipedia :

"En mai 2016, Microsoft a vidé son activité mobile, .... En 2017, le dirigeant de Microsoft Joe Belfiore a révélé que Microsoft avait cessé le développement de nouveaux téléphones Windows et de nouvelles fonctionnalités pour Windows 10 Mobile, citant les pertes de parts de marché et le manque de développement d'applications."
-- https://en.wikipedia.org/wiki/Microsoft_Mobile

Pourquoi DataGrid devrait-il continuer sur la même voie qui a détruit l'activité mobile de Microsoft ?

@verelpode

WinUI 3 continue les mêmes erreurs de gestion qui ont conduit à l'échec d'UWP et de Windows Phone et à la perte de plusieurs milliards de dollars de Microsoft.

Je ne travaille pas pour Microsoft mais je suis curieux de savoir pourquoi vous dites que WinUI fait des erreurs de gestion.
D'après ce que je vois, le fait même que WinUI soit open source et que tout le monde puisse contribuer aux conversations et aux décisions aide en fait à définir ce qu'est WinUI et devrait empêcher les erreurs de se produire.
Vous mentionnez que le DataGrid continue sur le même chemin que le mobile, mais nulle part sur le terrain je ne l'ai vu mentionner le mobile. Peut-être que vous pouvez garder vos commentaires directement sur ce dont cette question est discutée.
Si vous pensez qu'il y a des étapes de mauvaise gestion avec WinUI, vous pouvez peut-être créer un problème distinct avec vos préoccupations, mais je ne pense vraiment pas que vos commentaires aient quelque chose à voir avec le contrôle DataGrid.

@verelpode s'il vous plaît gardez vos commentaires ici sur le sujet. Si vous avez des inquiétudes concernant WinUI ou UWP en général, veuillez commencer un nouveau sujet de discussion ou contactez-moi directement (écrivez-moi ou DM sur Twitter). Ou vous pourriez envisager de discuter d'un sujet existant comme #717 ou #1531.

Vous avez fait part de vos inquiétudes quant à la réécriture de DataGrid en C++, mais en fait, la proposition originale ne mentionnait rien à ce sujet. @anawishnoff essaie de recueillir des commentaires sur l'ensemble de fonctionnalités DataGrid. Du point de vue de l'implémentation, s'il est le plus logique de le conserver en C#, nous le ferions (et il pourrait toujours être appelé à partir de C++ si nous le faisions en tant que composant WinRT).

@jevansaks -- Mes commentaires étaient sur le sujet, mais c'est dans la nature humaine de tirer sur le messager qui annonce la mauvaise nouvelle. Votre réponse me rend triste et déçu. D'accord, je vais arrêter d'essayer d'aider, car mon aide est indésirable car trop honnête et directe et touche à des problèmes douloureux trop douloureux à reconnaître et à résoudre (l'échec catastrophique de WinRT soulève trop d'émotions et c'est donc plus facile à effacer de mémoire et continuez le même vieux plan WinRT d'origine comme si le désastre ne s'était même jamais produit). Je vais quitter cette discussion et ne plus participer au développement de DataGrid, car continuer à parler honnêtement et directement des vrais problèmes ne fera qu'ennuyer les gens.

@verelpode Personne n'a "tiré sur le messager qui annonce la mauvaise nouvelle" ici. @jevansaks vous a invité à ouvrir un nouveau numéro pour partager vos préoccupations générales concernant UWP/WinUI/WinRT dans ce référentiel. Ce problème ne concerne vraiment que le DataGrid et bien qu'en effet l'une de vos préoccupations concernait DataGrid, la grande majorité concernait UWP/WinUI/WinRT en général. Je suis sûr que si vous regardez à nouveau cette discussion, vous verrez que l'équipe WinUI vous demande simplement de garder ce problème concentré uniquement sur la proposition DataGrid et d'ouvrir un nouveau/utiliser un problème existant pour vos préoccupations plus larges concernant le Plate-forme.

Les préoccupations que vous avez mentionnées peuvent être la base d'une discussion intéressante impliquant à la fois l'équipe WinUI et la communauté, mais ce problème particulier n'est pas adapté à une telle discussion.

@anawishnoff
Je suis presque sûr que le contrôle Microsoft Pivot Viewer n'était pas html. Veuillez le regarder en arrière. La possibilité de visualiser de grands ensembles de données en utilisant quelque chose comme ça était quelque chose que nous avons voulu faire parfois. Il était disponible en Silverlight je pense. https://www.microsoft.com/silverlight/pivotviewer/default# Il a utilisé Deep Zoom pour sa fonctionnalité. L'ajout de la capacité Deep Zoom à WinUI 3.0 serait fabuleux ! Pas vraiment le Datagrid, mais un contrôle Data Display. Il y a beaucoup d'idées "abandonnées" des premiers jours de WPF comme Deep Zoom qui n'ont jamais été transformées en un contrôle WPF de production qu'il serait merveilleux de faire revivre dans WinUI 3.0 au fil du temps. Allez sortir le Dr WPF du sous-sol et faites-le poster à nouveau !!! Nous avons besoin de lui. Nous devons lancer un mouvement. RAPPELEZ Dr WPF !!!!! Où es tu allé? Dr WinUI !!!

@PaulMontgomerySP semble que vous devriez ouvrir un nouveau problème pour discuter du contrôle Pivot. N'hésitez pas à faire référence à la discussion précédente qui a eu lieu à ce sujet dans la boîte à outils de la communauté Windows ici : https://github.com/windows-toolkit/WindowsCommunityToolkit/issues/770

La sélection a changé l'événement se déclenche pour chaque ligne vers laquelle je me déplace avec le clavier.
Ce serait bien d'avoir un événement uniquement pour un clic de souris ou une touche de cellule, au lieu de seulement l'événement de sélection modifié.

La sélection a changé l'événement se déclenche à la fois pour le clic et le clavier. Il serait grandement avantageux d'avoir un événement uniquement pour cliquer.

@Going-Gone Je suis curieux de savoir quel est le cas d'utilisation? Pourquoi avez-vous besoin de connaître la différence? Vous ne pouvez pas non plus utiliser l'événement tapé ?

Une limitation que je viens de frapper avec le DataGrid de l'UWP Toolkit est que le DataGridTemplateColumn a un CellTemplate, mais il n'a pas de CellTemplateSelector (et le même manque pour CellEditingTemplate ). Cela simplifierait l'adaptation de l'interface utilisateur dans chaque cellule aux données à l'aide de l'approche du sélecteur, plutôt que d'avoir à le faire avec un niveau supplémentaire de contrôles d'interface utilisateur en dessous pour gérer cela.

Veuillez également permettre de sélectionner des lignes non seulement dans un ordre consécutif, comme je l'ai expliqué en détail ici :
https://github.com/duke7553/files-uwp/issues/276#issue-520060100

Dans aucun ordre particulier de choses qui sont souvent demandées par les clients qu'une grille doit prendre en charge

1.Possibilité d'enregistrer, de charger et de créer des filtres. Par exemple, filtrer vers l'expression linq, filtrer vers la requête SQL, filtrer vers l'arbre d'expression et inversement. Exemple - https://querybuilder.js.org/demo.html

  1. Capacités de données en temps réel à haute vitesse, les performances sont importantes. Les taux de rafraîchissement inférieurs à 1 ms pour les applications de trading par rapport à > 1 million de lignes ont des considérations de performances différentes.
  2. Capacité de spécifier l'ordre de tri, p. ex. i. trier haut/bas, ii. trier bas/haut et iii. aucune sorte ou i. trier bas/haut, ii. trier haut/bas et iii. pas de tri
  3. Filtrage de type Excel
  4. Possibilité d'appliquer le formatage CSS aux cellules, formatage conditionnel
  5. Possibilité d'enregistrer/charger facilement les paramètres de grille, par exemple les filtres, les largeurs de colonnes, le tri, etc.
  6. Défilement qui fonctionne, par exemple ne se réinitialise pas après la mise à jour des données, fluide.
  7. Les événements de collecte de données doivent avoir des options pour déclencher des événements après le chargement des plages plutôt que des objets individuels. Par exemple, je pense que ObservableCollection nécessite une sous-classe pour empêcher le déclenchement de INotifyPropertyChange pour chaque objet individuel ajouté.
  8. Meilleurs événements pour le chargement/chargement des données, le démarrage du chargement des données, le chargement des données, les données chargées, en particulier si vous utilisez le chargement asynchrone.
  9. Les grilles sont souvent liées à d'autres contrôles tels que les filtres de données, la sélection de plage, le filtre croisé (par exemple https://github.com/dc-js/dc.js), les graphiques, les tableaux croisés dynamiques, etc.
  10. Tri intelligent qui gère les données alphanumériques, par exemple l'ordre de tri ABC11, ABC12, ABC111 au lieu de ABC11, ABC111, ABC12
  11. Niveaux illimités de grilles hiérarchiques, par exemple https://docs.telerik.com/devtools/wpf/controls/radgridview/hierarchical-gridview/hierachy-overview

Ressources utiles : - Concevoir de meilleurs tableaux de données
https://news.ycombinator.com/item?id=21460966
https://uxdesign.cc/design-better-data-tables-4ecc99d23356

Je ne pourrai pas lier directement à la largeur de colonne à partir de l'en-tête. Dans WPF, je dois utiliser un objet BindingProxy dans ce cas.

Redimensionnement dynamique pratique de la ligne active pour une édition plus facile.
Contrôle total des menus contextuels en mode édition.

J'espère qu'il prend en charge CellDecorationStyleSelector comme dans Telerik.

Accessibilité!
Le mentionner pour qu'il soit documenté, mais ce contrôle doit être entièrement accessible.
La version actuelle de la boîte à outils présente certaines limitations dans ce domaine : https://github.com/windows-toolkit/WindowsCommunityToolkit/issues/3400 & https://github.com/windows-toolkit/WindowsCommunityToolkit/issues/3079
De plus, bien que Telerik RadDataGrid possède d'excellentes fonctionnalités, il semble ne pas prendre en charge l'accessibilité .

Avec la grande poussée de Microsoft pour D&I, je suis surpris que les besoins pour que tous les contrôles soient entièrement accessibles ne soient pas spécifiés comme une exigence partout.

C'est peut-être déjà possible, et je ne sais pas encore comment y parvenir... mais qu'en est-il : un style de ligne ou de cellule personnalisé ?

La possibilité de cibler une ligne spécifique, de modifier l'arrière-plan et la couleur du texte serait formidable.

Par rapport au WCT UWP DataGrid :
1) Performances
2) Plus de types de colonnes intégrés (je suppose qu'ils ont de meilleures performances que les colonnes de modèle)
3) Possibilité d'accrocher des événements de souris par cellule, c'est-à-dire appuyer, appuyer avec le bouton droit et survoler (ou pointeur vers le bas ou autre)
4) Événements clavier par cellule
5) Si (3) n'est pas réalisable, nous pourrions émuler si nous avions une fonctionnalité de test d'impact
6) Performances

Combien de personnes s'opposeraient si WinUI DataGrid abandonnait la fonctionnalité permettant aux utilisateurs finaux de modifier les valeurs des cellules en ligne/directement à l'intérieur du DataGrid ?

Est-ce que quelqu'un se souvient de VB6 ? Le DataGrid VB6 a pris en charge Edit, Delete et AddNew prêts à l'emploi. Ajouter était disponible sous la forme d'une ligne vide automatiquement ajoutée à la fin de la liste. Complétez la ligne et une autre ligne vide apparaît.

Un DataGrid devrait avoir la possibilité de prendre en charge la saisie de données, même si la plupart des développeurs préfèrent que cette fonctionnalité soit désactivée par défaut.

Lors du portage d'une application VB6 vers UWP, nous avons dû écrire notre propre grille de données pour prendre en charge l'ajout/la modification/la suppression.

Il semble que la plupart des contributeurs ici soient des gens de WPF/Xaml, cela vaut deux cents de quelqu'un qui n'est pas un gars de xaml.

J'utilise beaucoup les contrôles DataGrid dans mon logiciel. L'édition est l'endroit est important ! Certains de mes souhaits/points douloureux sont :

  1. Possibilité de personnaliser le menu contextuel en mode édition.
  2. De meilleures performances et plus de contrôle lors du dimensionnement automatique des colonnes. Je veux que l'utilisateur puisse contrôler les tailles si nécessaire, mais surtout pas besoin. Je ne veux pas que la taille des colonnes change constamment, mais je veux qu'elles soient en quelque sorte basées sur des données sans avoir à mesurer la valeur d'un million de lignes de données.
  3. Lors de l'édition, je veux pouvoir cliquer sur un autre contrôle/bouton qui fait quelque chose avec (ou avec) les données en cours d'édition sans mettre fin à l'édition. (Ce serait moins nécessaire si #1 était implémenté - bien que toujours utile.)
  4. la manière actuelle dont les exceptions sont gérées à l'aide de l'événement DataError est approximative. (Désolé, j'ai du mal à être précis à ce sujet, mais je sais que cela m'a causé de la douleur plusieurs fois dans le passé.)
  5. Une capacité de défilement automatique intégrée serait bien : http://stackoverflow.com/questions/2567809/how-to-autoscroll-a-datagridview-during-drag-and-drop
  6. Possibilité d'afficher un « filigrane » indiquant quand les données sont « sales » (voir BetterGrid pour quelques améliorations supplémentaires utiles à DataGridView.
  7. Possibilité d'abandonner une ligne (sans erreur de validation) lorsque la cellule "clé" requise est laissée vide.
  8. Capacité intégrée de n'afficher aucune image (au lieu d'un X rouge) pour une ligne ajoutée par l'utilisateur. Voir : https://stackoverflow.com/questions/937919/datagridviewimagecolumn-red-x
  9. Permettre à une colonne de case à cocher de s'engager immédiatement en cas de modification : https://stackoverflow.com/questions/11843488/how-to-detect-datagridview-checkbox-event-change

Quand l'alpha devrait-il sortir ? Sera-t-il ouvert aux contributions ? J'essaie d'abandonner une grille de données obsolète et j'attends cela avec impatience, en particulier la fonctionnalité de virtualisation.

Désolé d'avoir apporté une contribution très tardive à ce fil, mais pour moi c'est "nouveau" ;)
_édité après en savoir un peu plus sur le comportement du contrôle_

En travaillant avec DataGrid pour créer une interface de type explorateur pour les lecteurs cloud, j'ai découvert que la détermination de la ligne et de la cellule sur lesquelles s'appuyer peut être un peu plus complexe qu'elle ne devrait l'être (IMHO)

Dans la conception de mon application, les lignes représentent des fichiers ou des dossiers (DriveItems). La vue détaillée affiche plus de détails sur l'élément.

Je voulais créer une possibilité de cliquer sur un élément de dossier, et faire sauter l'interface et créer une liste de ces éléments, permettant la navigation dans tout le lecteur.

image

Par exemple, si j'appuyais sur l'entrée de la colonne "Parent" de l'élément, /drive/root:/Documents/Vital%20Documents ici, l'interface serait réinitialisée dans ce dossier et y répertorierait les fichiers.

Bien que l'on puisse obtenir un événement cliqué pour la cellule, cet événement ne semble pas avoir le contexte permettant au gestionnaire de déterminer la cellule qui a été touchée (ligne, oui, mais pas colonne), et je ne suis pas sûr qu'actuellement le contrôle me permettrait d'avoir à la fois le comportement d'écoute de la cellule ET le comportement d'ouverture automatique des détails (enquêtant toujours sur ce que je pourrais appeler des "piratages" qui le permettraient, mais nous devons nous rappeler que lorsque les concepteurs commencent à outrepasser le fonctionnement normal du contrôle, en particulier pas des comportements qui sont documentés, ils courent le risque de voir la conception brisée par des changements dans le comportement du contrôle.

Cela dit, DataGrid semble prendre en charge mon scénario en ayant l'événement qui renvoie actuellement le DriveItem comme CurrentItem, devrait également inclure un CurrentColumn qui serait l'intégralité de l'objet DataGridColumn qui a été cliqué à l'intérieur, via dont il serait possible d'extraire le nom de la colonne. Je me rends compte maintenant que nous avons l'objet CurrentColumn que nous pouvons étudier à partir de l'événement, donc, même si je l'aimerais mieux comme argument de l'événement, cela devrait fonctionner.

En outre, un contrôle plus strict du comportement des détails pourrait être que les détails ne seraient automatiquement développés qu'en cliquant sur une colonne particulière, au lieu de se développer chaque fois que l'on cliquerait n'importe où dans la ligne.

Peut-être que la classe de base de l'objet DataGridColumn pourrait avoir une propriété ExpandDetails qui peut être définie sur true par défaut pour chaque colonne, ce qui signifierait que cette colonne particulière sur laquelle on clique entraîne l'expansion de la ligne. D'autres où la propriété est fausse ne le seraient pas.

Dans ma conception, par exemple, la première colonne est le type d'élément, comme dans Fichier ou Dossier, ou Image ou Photo, Audio, etc. Je pourrais envisager de configurer cette colonne pour qu'elle soit la seule à provoquer le comportement d'expansion automatique, puis un clic sur la colonne Chemin peut provoquer le comportement "obtenir une liste de ce chemin" que j'ai décrit ci-dessus.

Quant au tri, il semblerait logiquement important de mettre en œuvre un contrôle suffisant pour permettre aux concepteurs d'obtenir un tri à plusieurs niveaux. Je n'ai pas fait d'enquête pour déterminer comment le contrôle actuel pourrait prendre en charge cela par le biais d'événements et de rappels d'accrochage/de remplacement, mais cela ne semble pas simple.

Enfin, je sais que vous en êtes bien conscient, mais (même si je demande plus de fonctionnalités), évitons SVP d'essayer d'ajouter un tas de comportements complexes que les utilisateurs peuvent implémenter eux-mêmes au-dessus du DataGrid. Parmi ceux que je n'implémenterais pas dans DataGrid, il y en a qui ont à voir avec le stockage externe de filtres ou de tris, etc. J'éviterais également de transformer ce contrôle en un clone Excel.

-merci, super travail !
-e

Groupes persistants : lorsque vous parcourez des ensembles de données avec de grands groupes, il doit y avoir un contexte sur le groupe (ou les groupes, c'est-à-dire le fil d'Ariane) qui est affiché. Cela semble être une fonctionnalité d'utilisation essentielle pour toutes les vues hiérarchiques basées sur des listes : vues de liste groupées, grilles de données et vues arborescentes.

Je construirais le nouveau contrôle DataGrid au-dessus du nouveau contrôle WinUI ItemsRepeater. Et ce contrôle expose son ItemsSource en tant qu'objet :
Object ItemsSource { get; set; };

@RBrid Pour en revenir ~ 1 an plus tard. J'ai réalisé que ItemsRepeater, bien qu'il ait un objet ItemsSource, n'a pas réellement de support intégré pour les interfaces suivantes nécessaires pour travailler avec des sources de données virtualisées :

  • ISupportIncrementalLoading
  • IIArticlesRangeInfo
  • ISelectionInfo

-Que diriez-vous d'avoir un MVP là-dedans maintenant afin que nous puissions utiliser un Datagrid de c++.

Cette page vous a été utile?
0 / 5 - 0 notes