Dans le passé, les tableaux n'étaient pas toujours utilisés pour lier directement DataGridView, et il n'y avait aucun problème de ne pas pouvoir trier. Lorsque j'ai essayé List pour la première fois, j'ai découvert que la fonction de tri ne pouvait pas être implémentée quoi qu'il arrive.
Chaque colonne du DataGridView a un Sortable. La valeur par défaut est Automatique. Je l'ai changé en NotSortable. Quel que soit le résultat, cela ne fonctionne toujours pas.
Certains amis ont dit que vous pouvez faire glisser un contrôle bindsource.datasource=generic collection datagridview.datasource=bindingsource;
J'ai constaté que cela ne fonctionnait pas non plus, alors que dois-je faire ? À découvrir après avoir vérifié les informations
L'utilisation de génériques perdra les caractéristiques de DateTable. Vous devez implémenter System.Collections.Generic.IComparer<T> pour réaliser le tri.
Il n'y a pas d'autre moyen que de le réaliser
Jetez un œil au code ci-dessous, il ressemble essentiellement à ceci
code
utiliser le système ;
en utilisant System.ComponentModel ;
en utilisant System.Collections.Generic ;
en utilisant System.Reflection ;
espace de noms BaseFunction
{
classe ObjectPropertyCompare<T> : System.Collections.Generic.IComparer<T>
{
propriété privée PropertyDescriptor ;
direction privée ListSortDirection ;
public ObjectPropertyCompare (propriété PropertyDescriptor, direction ListSortDirection)
{
this.property = propriété ;
this.direction = direction;
}
#region IComparer<T>
/// <résumé>
/// Méthode de comparaison
/// </summary>
/// <param name="x">Attribut relatif x</param>
/// <param name="y">Attribut relatif y</param>
/// <retours></retours>
public int Comparer (T x, T y)
{
objet xValue = x.GetType().GetProperty(property.Name).GetValue(x, null);
objet yValue = y.GetType().GetProperty(property.Name).GetValue(y, null);
int valeur de retour ;
si (xValue est IComparable)
{
returnValue = ((IComparable)xValue).CompareTo(yValue);
}
sinon si (xValue.Equals(yValue))
{
valeur de retour = 0 ;
}
autre
{
returnValue = xValue.ToString().CompareTo(yValue.ToString());
}
si (direction == ListSortDirection.Ascending)
{
retourner valeur de retour ;
}
autre
{
return valeur de retour * -1 ;
}
}
public bool Égal à (T xWord, T yWord)
{
return xWord.Equals(yWord);
}
public int GetHashCode (T obj)
{
return obj.GetHashCode();
}
#endregion
}
}
Après avoir implémenté cette interface, rien ne presse. Nous devons écrire une classe SortableBindingList <T> :BindingList <T> pour lier les données.
Implémentation de base
code
utiliser le système ;
en utilisant System.ComponentModel ;
en utilisant System.Collections.Generic ;
en utilisant System.IO ;
en utilisant System.Runtime.Serialization.Formatters.Binary ;
en utilisant System.Text ;
espace de noms BaseFunction
{
classe publique BindingCollection<T> : BindingList<T>
{
le bool privé estSorted ;
private PropertyDescriptor sortProperty ;
privé ListSortDirection sortDirection ;
bool de remplacement protégé IsSortedCore
{
obtenir { return isSorted }
}
protection override bool SupportsSortingCore
{
obtenir { retourner vrai }
}
remplacement protégé ListSortDirection SortDirectionCore
{
obtenir { return sortDirection }
}
remplacement protégé PropertyDescriptor SortPropertyCore
{
obtenir { return sortProperty }
}
protected override bool SupportsSearchingCore
{
obtenir { retourner vrai }
}
protected override void ApplySortCore (propriété PropertyDescriptor, direction ListSortDirection)
{
List<T> items = this.Items as List<T> ;
si (articles != null)
{
ObjectPropertyCompare<T> pc = new ObjectPropertyCompare<T>(propriété, direction);
articles.Sort(pc);
estSorted = vrai ;
}
autre
{
estSorted = faux ;
}
sortProperty = propriété ;
sortDirection = direction ;
this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
}
remplacement protégé void RemoveSortCore()
{
estSorted = faux ;
this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
}
//Trier
public void Sort (propriété PropertyDescriptor, direction ListSortDirection)
{
this.ApplySortCore(propriété, direction);
}
}
}
Il est maintenant temps de comprendre comment l’utiliser. C’est en fait très simple.
direct
BindingCollection<objet> objList = new BindingCollection<objet>();
objList = votre jeu de résultats ;
this.dataGridView1.DataSource = objList ;
Mais maintenant, le problème est que j'ai utilisé List auparavant et je ne veux pas le changer. De plus, la DLL est appelée et ce qui est renvoyé est une liste, je n'ai aucun moyen de la changer en BindingCollection<object>.
Après y avoir longuement réfléchi, j'ai finalement compris, mais je ne sais pas comment ça se passe en termes de performances et d'autres aspects, alors je vais poster le code et en discuter.
C'est comme ça que j'y suis parvenu
code
//Classes pouvant implémenter le tri
BindingCollection<historyorderInfo> objList = new BindingCollection<historyorderInfo>();
//Charger les données
foreach (élément historyorderInfo dans tmpList)
{
objList.Add(élément);
}
dgvhistory.DataSource = objList;
La tmpList ici est la liste originale du système que j'ai utilisé auparavant. J'ai utilisé foreach pour importer les données originales dans BindingCollection.
Cette détermination peut produire l’effet que je souhaite. Je ne sais pas ce qui ne va pas. J'espère pouvoir obtenir l'avis d'un expert, haha