IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

DataTable et List<T> [Débutant]


Sujet :

C#

  1. #1
    Membre du Club
    Homme Profil pro
    Inscrit en
    Octobre 2013
    Messages
    143
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2013
    Messages : 143
    Points : 43
    Points
    43
    Par défaut DataTable et List<T>
    Bonjour,

    Voici mon petit soucis. J'ai un programme dans lequel je remplis un DataGridView avec une liste d'objet (de classe Employee par exemple).
    En faisant cette méthode je peux par la suite pour d'autres fonctionnalités récupérer le type de l'objet avec la propriété DataBoundItem de DataGridViewRow lorsque je sélectionne une ligne (pour ensuite faire une conversion tel que "if (dgvRow.DataBoundItem is Employee emp)").

    Le soucis, c'est qu'en remplissant un DataGridView avec une liste on ne dispose pas des fonctionnalités de tri sur les colonnes.

    Du coup, j'ai convertis ma liste d'object en DataTable qui est par la suite utilisé pour le DataGridView. Sauf que, en faisant cela je perd l'information du type de base de mon objet (Employee) quand je fais le DataBoundItem. Le type devient "System.Data.DataRowView".

    Y-a-t-il un moyen de récupérer le type de base de l'objet avant qu'il ne devienne un DataRow ?

    Solution testée et non concluante :
    - Convertir le DataRow en Employee : trop complexe à mettre en place du fait que certains paramètres de ma classe sont uniquement en ReadOnly (peux pas changer cela).

    Merci d'avance pour vos retours

  2. #2
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 442
    Points
    4 442
    Par défaut
    bonjour

    Y-a-t-il un moyen de récupérer le type de base de l'objet avant qu'il ne devienne un DataRow ?
    Aucun.A ma connaissance la mutation de Type n'existe pas.

    Un control DataGridView "bindé" à un List<T> ne peut pas être trié, car le List<T> ne supporte pas le tri...
    Le fait que un DataGridView "bindé" à un DataTable supporte le tri par colonne est du en fait à la prop DataTable.View auquel il est "bindé" en coulisse (et DataView implémente le tri)...
    Pour contourner cet recueil le seul moyen est d’implémenter un custom
    List <T> dérive de BindingList<T> & son "companion" PropertyComparer<T> dont voici le code :
    1/ class "companion" PropertyComparer<T>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
     
    namespace WinSortableList
    {
        public class PropertyComparer<T> : IComparer<T>
        {
            private readonly IComparer comparer;
            private PropertyDescriptor propertyDescriptor;
            private int reverse;
     
            public PropertyComparer(PropertyDescriptor property, ListSortDirection direction)
            {
                this.propertyDescriptor = property;
                Type comparerForPropertyType = typeof(Comparer<>).MakeGenericType(property.PropertyType);
                this.comparer = (IComparer)comparerForPropertyType.InvokeMember("Default", BindingFlags.Static | BindingFlags.GetProperty | BindingFlags.Public, null, null, null);
                this.SetListSortDirection(direction);
            }
     
            #region IComparer<T> Members
     
            public int Compare(T x, T y)
            {
                return this.reverse * this.comparer.Compare(this.propertyDescriptor.GetValue(x), this.propertyDescriptor.GetValue(y));
            }
     
            #endregion
     
            private void SetPropertyDescriptor(PropertyDescriptor descriptor)
            {
                this.propertyDescriptor = descriptor;
            }
     
            private void SetListSortDirection(ListSortDirection direction)
            {
                this.reverse = direction == ListSortDirection.Ascending ? 1 : -1;
            }
     
            public void SetPropertyAndDirection(PropertyDescriptor descriptor, ListSortDirection direction)
            {
                this.SetPropertyDescriptor(descriptor);
                this.SetListSortDirection(direction);
            }
        }
    2/ class SortableBindingList<T>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
     
    namespace WinSortableList
    {
        public class SortableBindingList<T> : BindingList<T>
        {
            private readonly Dictionary<Type, PropertyComparer<T>> comparers;
            private bool isSorted;
            private ListSortDirection listSortDirection;
            private PropertyDescriptor propertyDescriptor;
     
            public SortableBindingList()
                : base(new List<T>())
            {
                this.comparers = new Dictionary<Type, PropertyComparer<T>>();
            }
     
            public SortableBindingList(IEnumerable<T> enumeration)
                : base(new List<T>(enumeration))
            {
                this.comparers = new Dictionary<Type, PropertyComparer<T>>();
            }
     
            protected override bool SupportsSortingCore
            {
                get { return true; }
            }
     
            protected override bool IsSortedCore
            {
                get { return this.isSorted; }
            }
     
            protected override PropertyDescriptor SortPropertyCore
            {
                get { return this.propertyDescriptor; }
            }
     
            protected override ListSortDirection SortDirectionCore
            {
                get { return this.listSortDirection; }
            }
     
            protected override bool SupportsSearchingCore
            {
                get { return true; }
            }
     
            protected override void ApplySortCore(PropertyDescriptor property, ListSortDirection direction)
            {
                List<T> itemsList = (List<T>)this.Items;
     
                Type propertyType = property.PropertyType;
                PropertyComparer<T> comparer;
                if (!this.comparers.TryGetValue(propertyType, out comparer))
                {
                    comparer = new PropertyComparer<T>(property, direction);
                    this.comparers.Add(propertyType, comparer);
                }
     
                comparer.SetPropertyAndDirection(property, direction);
                itemsList.Sort(comparer);
     
                this.propertyDescriptor = property;
                this.listSortDirection = direction;
                this.isSorted = true;
     
                this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
            }
     
            protected override void RemoveSortCore()
            {
                this.isSorted = false;
                this.propertyDescriptor = base.SortPropertyCore;
                this.listSortDirection = base.SortDirectionCore;
     
                this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
            }
     
            protected override int FindCore(PropertyDescriptor property, object key)
            {
                int count = this.Count;
                for (int i = 0; i < count; ++i)
                {
                    T element = this[i];
                    if (property.GetValue(element).Equals(key))
                    {
                        return i;
                    }
                }
     
                return -1;
            }
        }
    3/ code du class data exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
    namespace WinSortableList
    {
        public class Person
        {
            private int id;
            private string firstName;
            public Person()
            {
     
            }
            public Person(int id, string firstName)
            {
                this.id = id;
                this.firstName = firstName;
            }
     
            public int Id
            {
                get { return this.id; }
                set { this.id = value; }
            }
     
            public string Firstname
            {
                get { return this.firstName; }
                set { this.firstName = value; }
            }
     
     
            public void SendInvoice()
            {
                MessageBox.Show( Firstname);
            }
     
        }
    4/ code exemple du form user:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
     
    namespace WinSortableList
    {
        public partial class Form1 : Form
        {
            private SortableBindingList<Person> myList = new SortableBindingList<Person>();
     
            public Form1()
            {
                InitializeComponent();
            }
     
            private void Form1_Load(object sender, EventArgs e)
            {
                myList = new SortableBindingList<Person>();
                myList.Add(new Person(1, "Tim"));
                myList.Add(new Person(2, "Amy"));
                myList.Add(new Person(3, "Sarah"));
                myList.Add(new Person(4, "Mike"));
     
     
                this.dgv.DataSource = myList;
     
            }
     
     
            private void button1_Click(object sender, EventArgs e)
            {
                foreach (DataGridViewRow row in this.dgv.SelectedRows)
                {
                    Person person = row.DataBoundItem as Person;
                    if (person != null)
                    {
                        person.SendInvoice();
                    }
                }
     
            }
     
        }
    }
    bon code...

  3. #3
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 442
    Points
    4 442
    Par défaut
    bonjour

    Y-a-t-il un moyen de récupérer le type de base de l'objet avant qu'il ne devienne un DataRow ?
    Aucun.A ma connaissance la mutation de Type n'existe pas.

    Un control DataGridView "bindé" à un List<T> ne peut pas être trié, car le List<T> ne supporte pas le tri...
    Le fait que un DataGridView "bindé" à un DataTable supporte le tri par colonne est du en fait à la prop DataTable.View auquel il est "bindé" en coulisse (et DataView implémente le tri)...
    Pour contourner cet recueil le seul moyen est d’implémenter un custom
    List <T> dérive de BindingList<T> & son "companion" PropertyComparer<T> dont voici le code :
    1/ class "companion" PropertyComparer<T>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
     
    namespace WinSortableList
    {
        public class PropertyComparer<T> : IComparer<T>
        {
            private readonly IComparer comparer;
            private PropertyDescriptor propertyDescriptor;
            private int reverse;
     
            public PropertyComparer(PropertyDescriptor property, ListSortDirection direction)
            {
                this.propertyDescriptor = property;
                Type comparerForPropertyType = typeof(Comparer<>).MakeGenericType(property.PropertyType);
                this.comparer = (IComparer)comparerForPropertyType.InvokeMember("Default", BindingFlags.Static | BindingFlags.GetProperty | BindingFlags.Public, null, null, null);
                this.SetListSortDirection(direction);
            }
     
            #region IComparer<T> Members
     
            public int Compare(T x, T y)
            {
                return this.reverse * this.comparer.Compare(this.propertyDescriptor.GetValue(x), this.propertyDescriptor.GetValue(y));
            }
     
            #endregion
     
            private void SetPropertyDescriptor(PropertyDescriptor descriptor)
            {
                this.propertyDescriptor = descriptor;
            }
     
            private void SetListSortDirection(ListSortDirection direction)
            {
                this.reverse = direction == ListSortDirection.Ascending ? 1 : -1;
            }
     
            public void SetPropertyAndDirection(PropertyDescriptor descriptor, ListSortDirection direction)
            {
                this.SetPropertyDescriptor(descriptor);
                this.SetListSortDirection(direction);
            }
        }
    2/ class SortableBindingList<T>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
     
    namespace WinSortableList
    {
        public class SortableBindingList<T> : BindingList<T>
        {
            private readonly Dictionary<Type, PropertyComparer<T>> comparers;
            private bool isSorted;
            private ListSortDirection listSortDirection;
            private PropertyDescriptor propertyDescriptor;
     
            public SortableBindingList()
                : base(new List<T>())
            {
                this.comparers = new Dictionary<Type, PropertyComparer<T>>();
            }
     
            public SortableBindingList(IEnumerable<T> enumeration)
                : base(new List<T>(enumeration))
            {
                this.comparers = new Dictionary<Type, PropertyComparer<T>>();
            }
     
            protected override bool SupportsSortingCore
            {
                get { return true; }
            }
     
            protected override bool IsSortedCore
            {
                get { return this.isSorted; }
            }
     
            protected override PropertyDescriptor SortPropertyCore
            {
                get { return this.propertyDescriptor; }
            }
     
            protected override ListSortDirection SortDirectionCore
            {
                get { return this.listSortDirection; }
            }
     
            protected override bool SupportsSearchingCore
            {
                get { return true; }
            }
     
            protected override void ApplySortCore(PropertyDescriptor property, ListSortDirection direction)
            {
                List<T> itemsList = (List<T>)this.Items;
     
                Type propertyType = property.PropertyType;
                PropertyComparer<T> comparer;
                if (!this.comparers.TryGetValue(propertyType, out comparer))
                {
                    comparer = new PropertyComparer<T>(property, direction);
                    this.comparers.Add(propertyType, comparer);
                }
     
                comparer.SetPropertyAndDirection(property, direction);
                itemsList.Sort(comparer);
     
                this.propertyDescriptor = property;
                this.listSortDirection = direction;
                this.isSorted = true;
     
                this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
            }
     
            protected override void RemoveSortCore()
            {
                this.isSorted = false;
                this.propertyDescriptor = base.SortPropertyCore;
                this.listSortDirection = base.SortDirectionCore;
     
                this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
            }
     
            protected override int FindCore(PropertyDescriptor property, object key)
            {
                int count = this.Count;
                for (int i = 0; i < count; ++i)
                {
                    T element = this[i];
                    if (property.GetValue(element).Equals(key))
                    {
                        return i;
                    }
                }
     
                return -1;
            }
        }
    3/ code du class data exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
    namespace WinSortableList
    {
        public class Person
        {
            private int id;
            private string firstName;
            public Person()
            {
     
            }
            public Person(int id, string firstName)
            {
                this.id = id;
                this.firstName = firstName;
            }
     
            public int Id
            {
                get { return this.id; }
                set { this.id = value; }
            }
     
            public string Firstname
            {
                get { return this.firstName; }
                set { this.firstName = value; }
            }
     
     
            public void SendInvoice()
            {
                MessageBox.Show( Firstname);
            }
     
        }
    4/ code exemple du form user:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
     
    namespace WinSortableList
    {
        public partial class Form1 : Form
        {
            private SortableBindingList<Person> myList = new SortableBindingList<Person>();
     
            public Form1()
            {
                InitializeComponent();
            }
     
            private void Form1_Load(object sender, EventArgs e)
            {
                myList = new SortableBindingList<Person>();
                myList.Add(new Person(1, "Tim"));
                myList.Add(new Person(2, "Amy"));
                myList.Add(new Person(3, "Sarah"));
                myList.Add(new Person(4, "Mike"));
     
     
                this.dgv.DataSource = myList;
     
            }
     
     
            private void button1_Click(object sender, EventArgs e)
            {
                foreach (DataGridViewRow row in this.dgv.SelectedRows)
                {
                    Person person = row.DataBoundItem as Person;
                    if (person != null)
                    {
                        person.SendInvoice();
                    }
                }
     
            }
     
        }
    }
    bon code...

  4. #4
    Membre du Club
    Homme Profil pro
    Inscrit en
    Octobre 2013
    Messages
    143
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2013
    Messages : 143
    Points : 43
    Points
    43
    Par défaut
    Merci pour ton retour

    J'ai trouvé une solution de contournement entre temps pour me débloqué qui n'est pas forcément propre mais qui fonctionne ^^

    En gros, en plus de ma DataTable j'ai gardé ma liste qui me sert à comparer les objets avec le DataGridView pour voir si tout est ok pour mes traitements ultérieurs.

    Je garde quand même ta solution de côté car je pense quelle va m'être utile plus tard

    Merci en tout cas.

    Je vais clore le sujet du coup

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. convertir datatable en list
    Par bonophil dans le forum C#
    Réponses: 7
    Dernier message: 05/10/2012, 14h10
  2. Ressouces nécessaires DataTable ou List<T>
    Par olibara dans le forum C#
    Réponses: 10
    Dernier message: 12/09/2009, 19h53
  3. probleme affichage Liste <dataTable
    Par skanderb dans le forum JSF
    Réponses: 1
    Dernier message: 25/04/2007, 11h10
  4. Liste de listes et dataTable
    Par mymyma dans le forum JSF
    Réponses: 1
    Dernier message: 29/08/2006, 10h36
  5. [JSF] DataTable et liste
    Par Ahmed0012 dans le forum JSF
    Réponses: 1
    Dernier message: 27/05/2006, 03h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo