IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
logo
Sommaire > WinForms > Contrôles de liste
        Comment sélectionner via le code une ligne d'un DataGrid ?
        Comment sélectionner toute la ligne lors d'un click dans une cellule ?
        Comment renommer une colonne de DataGrid ?
        Comment masquer une colonne de DataGrid ?
        Comment modifier la hauteur des lignes du DataGrid ?
        Comment dimensionner automatiquement la hauteur des lignes du DataGrid ?
        Comment implémenter l'évènement CurrentRowChanged du DataGrid ?
        Comment identifier la partie cliquée du DataGrid ?
        Comment obtenir le nombre de lignes du DataGrid par son BindingContext ?
        Comment capturer un clic dans l'icône d'un TreeNode ?
        Comment déterminer le TreeNode survolé par la souris ?
        Comment colorier une cellule en mode Details ?
        Comment trier les colonnes d'une listview en cliquant sur leurs intitulés ?



Comment sélectionner via le code une ligne d'un DataGrid ?
auteur : swoög
Il suffit simplement d'utiliser une méthode native des DataGrid :
(On suppose que MyDG est un DataGrid fonctionnel & Num_Row un entier contenant l'index de la colonne)
MyDG.Select(Num_Row);

Comment sélectionner toute la ligne lors d'un click dans une cellule ?
auteur : neguib
La Classe System.Windows.Forms.DataGrid.HitTestInfo vous permet de déterminer la partie d'un contrôle DataGrid sur laquelle l'utilisateur a cliqué. Pour ce faire, vous avez besoin d'utiliser la méthode HitTest du Datagrid que nous nommons ici pour l'exemple 'DG' :

          
		using System;
		using System.Drawing;
		using System.Windows.Forms;
		//...
		
        private void DG_MouseUp(object sender, MouseEventArgs e)
        {
            //recupérer les coordonnées de la souris
            Point p = new Point(e.X, e.Y);
            //déterminer la partie cliquée du datagrid
            DataGrid.HitTestInfo HTI = DG.HitTest(p);
            //si c'est un type 'cellule'
            if (HTI.Type == DataGrid.HitTestType.Cell)
            {
                //définir la cellule en cours
                DG.CurrentCell = new DataGridCell(HTI.Row, HTI.Column);
                //selectionner la ligne correspondante
                DG.Select(HTI.Row);
            }
        }

        
lien : fr System.Windows.Forms.DataGrid.HitTestInfo (MSDN)

Comment renommer une colonne de DataGrid ?
auteur : crjo
On suppose que le DataGrid est associé à une DataTable. Il faut effectuer les actions suivantes : 1. créer un DataGridTableStyle pour la table en question ; 2. ajouter le style au DataGrid ; 3. renommer la propriété HeaderText du style de colonne (DataGridColumnStyle) correspondant.

          
            // table est une DataTable
            dataGrid1.DataSource = table;

            // on crée une table de style qui permettra de renommer les colonnes.
            DataGridTableStyle tableStyle = new DataGridTableStyle();

            // IMPORTANT: il faut associer le nom de la table au style
            tableStyle.MappingName = table.TableName;

            // en ajoutant le style au DataGrid, les DataGridColumnStyle sont automatiquement créés
            // en fonction de la table spécifiée par tableStyle.MappingName
            dataGrid1.TableStyles.Add(tableStyle);


            // on suppose que la table contient une colonne nommée "col_name"

            tableStyle.GridColumnStyles["col_name"].HeaderText = "colonne renommée pour datagrid";

        
Le titre dans la colonne sera bien celui assigné, et on n'a pas touché à la structure interne de la table.


Comment masquer une colonne de DataGrid ?
auteur : crjo
On suppose que le DataGrid est associé à une DataTable. Il faut effectuer les actions suivantes :

  1. créer un DataGridTableStyle pour la table en question ;
  2. ajouter le style au DataGrid ;
  3. personnaliser le style pour retirer le style de colonne (DataGridColumnStyle) correspondant.

          
            // table est de type : DataTable
            dataGrid1.DataSource = table;

            // on crée une table de style qui permettra de masquer une ou plusieurs colonnes.
            DataGridTableStyle tableStyle = new DataGridTableStyle();

            // IMPORTANT: il faut associer le nom de la table au style
            tableStyle.MappingName = table.TableName;

            // en ajoutant le style au DataGrid, celui-ci va automatiquement utiliser le style
            // pour afficher la table associé (c'est pour ça qu'il est important
            // d'assigner MappingName)
            dataGrid1.TableStyles.Add(tableStyle);

            // on suppose que la table contient une colonne nommée "hidden"

            // on définit une référence sur la colonne que l'on veut cacher
            DataGridColumnStyle hiddenColStyle = tableStyle.GridColumnStyles["hidden"];

            // en enlevant la colonne des styles de colonne, la colonne n'apparaîtra
            // plus dans le DataGrid.
            tableStyle.GridColumnStyles.Remove(hiddenColStyle);


        
Astuce : en gardant une référence sur le style de colonne supprimée (hiddenColStyle), on peut par la suite décider de réafficher la colonne. Cette technique est utile si on veut choisir dynamiquement les colonnes à afficher.
tableStyle.GridColumnStyles.Add(hiddenColStyle);

Comment modifier la hauteur des lignes du DataGrid ?
auteur : neguib
Ici, le souci à résoudre est que l'accesseur DataGrid.DataGridRows est déclaré internal. Cette propriété expose le tableau des objets DataGridRow, elle même classe internal de System.Windows.Forms. Pour atteindre sa propriété Height, il y a tout de même une solution qui passe par les fonctionnalités de System.Windows.Reflection. Pour la démonstration, nous implémentons notre propre classe MonDataGrid dérivée de DataGrid :

          
    using System;
    using System.Reflection;
    using System.Windows.Forms;

    public class MonDataGrid : DataGrid
    {
        public MonDataGrid()
            : base()
        { }

        //...

        //méthode publique qui permet la modification
        // de la hauteur de la ligne indiquée
        public void setRowHeight(int rowindex, int rowheight)
        {
            //Recupérer le tableau des lignes
            Object[] rows = GetRows();

            //Ici par convention on décide de modifier
            // toutes les lignes pour une valeur négative
            if (rowindex < 0)
            {
                foreach (object row in rows)
                { setHeight(row, rowheight); }
            }
            else
            { setHeight(rows[rowindex], rowheight); }
        }

        //obtient toutes les lignes par reflection
        private object[] GetRows()
        {
            BindingFlags bf = BindingFlags.Instance | BindingFlags.NonPublic;
            Type t = this.GetType().BaseType;
            MethodInfo mi = t.GetMethod("get_DataGridRows", bf);
            return ((Object[])(mi.Invoke(this, null)));
        }

        //modifie la hauteur de ligne par reflection
        private void setHeight(object row, int rowheight)
        { row.GetType().GetProperty("Height").SetValue(row, rowheight, null); }

    }

        

Comment dimensionner automatiquement la hauteur des lignes du DataGrid ?
auteur : neguib
Dans un premier temps, il faut d'abord savoir Comment modifier la hauteur des lignes du DataGrid ?.
Nous utiliserons cette classe MonDataGrid dérivée de DataGrid et notamment sa méthode publique setRowHeight.

          
    using System;
    using System.Drawing;
    using System.Reflection;
    using System.Windows.Forms;

    public class MonDataGrid : DataGrid
    {
        //...

        //méthode publique qui dimensionne automatiquement la hauteur des lignes
        public void AutoSizeRows()
        {
            using (Graphics g = Graphics.FromHwnd(this.Handle))
            {
                SizeF s = g.MeasureString("test", this.Font);
                int h = Convert.ToInt32(s.Height);
                h += 8;
                setRowHeight(-1, h);
            }
        }

    }


        

Comment implémenter l'évènement CurrentRowChanged du DataGrid ?
auteur : neguib
La classe DataGrid ne possède nativement que l'évènement CurrentCellChanged pour signaler le changement de cellule. Il nous faut donc simplement, lors de cet évènement, comparer la ligne à laquelle correspond la cellule avec un champ privé représentant la ligne précedemment sélectionnée. Ainsi nous pouvons déclencher un nouvel évènement que nous appelons CurrentRowChanged à partir de la surcharge de la méthode DataGrid.OnCurrentCellChanged. Nous implémenterons une classe MonDataGrid dérivée de DataGrid capable de déclencher un évènement CurrentRowChanged pour signaler la ligne ayant actuellement le focus et, par là même, distinguer celle correspondant à l'ajout d'un enregistrement.

          
    using System;
    using System.Drawing;
    using System.Reflection;
    using System.Windows.Forms;

    public class MonDataGrid : DataGrid
    {
        public event EventHandler CurrentRowChanged;
        public MonDataGrid()
            : base()
        { this.currentRowIndex = -1; }
        //...

        //accesseur publique qui obtient l'index de la ligne courante
        public int CurrentRow
        { get { return this.currentRowIndex; } }
        private int currentRowIndex;

        //surcharge de la méthode base.OnCurrentCellChanged
        protected override void OnCurrentCellChanged(EventArgs e)
        {
            base.OnCurrentCellChanged(e);
            if (this.CurrentCell.RowNumber != this.currentRowIndex)
            {
                this.currentRowIndex = this.CurrentCell.RowNumber;
                this.OnCurrentRowChanged(e);
            }
        }
        //déclenche l'évènement CurrentRowChanged
        protected virtual void OnCurrentRowChanged(EventArgs e)
        {
            if (this.CurrentRowChanged != null)
            { this.CurrentRowChanged(this, e); }
        }

    }


        
Utilisable par exemple ainsi :

          
        private void DataGrid1CurrentRowChanged(object sender, System.EventArgs e)
        {
            MonDataGrid dg = (MonDataGrid)sender;
            int rowindex = dg.CurrentRow;
            if (rowindex == ((DataTable)dg.DataSource).Rows.Count)
            { this.LComment.Text = "Vous êtes sur la ligne d'ajout d'enregistrement"; }
            else
            { this.LComment.Text = "ligne " + rowindex.ToString(); }
        }


        

Comment identifier la partie cliquée du DataGrid ?
auteur : neguib
La Classe DataGrid.HitTestInfo vous permet de déterminer la partie d'un contrôle DataGrid sur laquelle l'utilisateur a cliqué. Pour ce faire, il nous faut :

  1. Déterminer les coordonnées du click par la méthode HitTest ;
  2. Utiliser la propriété HitTestInfo.Type, qui renvoie une valeur de l'énumération DataGrid.HitTestType.
Nous implémenterons une classe MonDataGrid dérivée de DataGrid capable d'exposer par un accesseur sa partie cliquée.

          
        public class MonDataGrid : DataGrid
        {
            //...

            //accesseur publique qui obtient la partie cliquée
            public DataGrid.HitTestType ClickType
            { get { return this.currentClickType; } }

            private DataGrid.HitTestType currentClickType;

            //surcharge de base.OnMouseDown
            protected override void OnMouseDown(MouseEventArgs e)
            {
                this.currentClickType = this.HitTest(e.X, e.Y).Type;
                base.OnMouseDown(e);
            }
        }

        
Utilisable, par exemple, de la façon suivante :

          
		using System.Text;
		//...

		private void DataGrid1MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            MonDataGrid dg = (MonDataGrid)sender;

            StringBuilder sb = new StringBuilder("La partie cliquée est de type: ");
            sb.Append(dg.ClickType.ToString());

            dg.CaptionText = sb.ToString();
        }

        
lien : System.Windows.Forms.DataGrid.HitTestType (MSDN)

Comment obtenir le nombre de lignes du DataGrid par son BindingContext ?
auteur : neguib
La propriété DataGrid.BindingContext permet d'accéder à l'indexeur de l'objet BindingManagerBase sous-jascent. Et par là même, permet d'atteindre sa propriété BindingManagerBase.Count. Pour la démonstration, nous implémentons notre propre classe MonDataGrid dérivée de DataGrid.

          
        public class MonDataGrid : DataGrid
        {
            //...

            //accesseur publique qui obtient le nombre de lignes
            public int DataRowsCount
            { get { return this.currentDataRowsCount; } }

            private int currentDataRowsCount;

            //surcharge de la méthode base.OnDataSourceChanged
            protected override void OnDataSourceChanged(System.EventArgs e)
            {
                if (this.DataSource != null)
                { this.currentDataRowsCount = this.BindingContext[this.DataSource, this.DataMember].Count; }
                else
                { this.currentDataRowsCount = 0; }

                base.OnDataSourceChanged(e);
            }
        }

        
Utilisable par exemple ainsi sur une modification DataGrid.DataSource :

          
		using System.Text;
		//...

        private void DataGrid1DataSourceChanged(object sender, EventArgs e)
        {
            StringBuilder sb = new StringBuilder("Le nombre de lignes est de: ");
            sb.Append(((MonDataGrid)sender).DataRowsCount.ToString());

            this.LComment.Text = sb.ToString();
        }

        
Cet exemple peut bien évidemment être amélioré, si l'on souhaite également répercuter de façon dynamique des ajouts ou suppressions de lignes.


Comment capturer un clic dans l'icône d'un TreeNode ?
auteur : neguib
Utilisons un TreeView appelé ici "TreeView1" possédant nécessairement dans ce cas de figure une ImageList pour sa collection de TreeNode.
La capture de l'évènement Click se fait ici par la méthode TreeView.MouseDown afin de récupérer les coordonnées du pointeur de la souris.
La méthode ci-dessous GetNodeIconeRectangle permet de calculer le Rectangle de l'icone du TreeNode sélectionné. Il ne reste plus alors qu'à vérifier si le Point localisé du pointeur de la souris appartient à l'icone du TreeNode sélectionné.

          
		using System;
		using System.Drawing;
		using System.Windows.Forms;

        private void TreeView1_MouseDown(object sender, MouseEventArgs e)
        {
            Point p = new Point(e.X, e.Y);
            TreeNode selectedTreeNode = this.TreeView1.GetNodeAt(p);
            Rectangle imgRectangle;
            if (selectedTreeNode != null)
            {
                imgRectangle = GetNodeIconeRectangle(selectedTreeNode);
                if (imgRectangle.Contains(p))
                {
                    //traitement
                }
            }
        }

        private Rectangle GetNodeIconeRectangle(TreeNode node)
        {
            Size s = node.TreeView.ImageList.ImageSize;
            int h = node.TreeView.ItemHeight;
            int x = node.Bounds.X - s.Width;
            int y = node.Bounds.Y + ((h - s.Height) / 2);
            return new Rectangle(new Point(x, y), s);
        }
        

Comment déterminer le TreeNode survolé par la souris ?
auteur : cardi
Il faut pour cela traiter l'évènement MouseMove du TreeView :

          
      /// <summary>
      /// Evènement MouseMove du treeView1
      /// </summary>
      private void treeView1_MouseMove(object sender, MouseEventArgs e)
      {
          // Récupération du TreeNode survolé
          TreeNode currentNode = treeView1.GetNodeAt(e.X, e.Y);

          // Vérification que la souris survole bien un TreeNode
          if (currentNode != null)
              Console.WriteLine("Le node survolé est {0}", currentNode.Name);
      }
      
        

Comment colorier une cellule en mode Details ?
auteur : neguib
L'objet ListViewSubItem a une propriété BackColor mais pour que l'assignation soit effective il ne faut pas oublier de modifier la propriété UseItemStyleForSubItems du ou des ListViewItem concerné(s) en lui attribuant la valeur false.
Si vous souhaitez effectuer cette opération par programmation, voici un exemple :
- Coloration en jaune de toute la première colonne d'un ListView1 :

          
	using System;
	using System.Drawing;
	using System.Windows.Forms;
	//...

	foreach (ListViewItem lvi in this.ListView1.Items)
	{
		lvi.UseItemStyleForSubItems = false;
		lvi.SubItems[0].BackColor = Color.Yellow;
	}
	this.ListView1.View = View.Details;

        
lien : fr System.Windows.Forms.ListView (MSDN)

Comment trier les colonnes d'une listview en cliquant sur leurs intitulés ?
auteur : nico-pyright(c)
L'objet ListView dispose d'une propriété ListViewItemSorter de type IComparer. Cela permet d'implémenter sa propre gestion du tri.
Pour ce faire, il faut créer une classe dérivant de IComparer implémentant la méthode Compare.

          
        class ListViewItemComparer : IComparer
        {
            private int col;
            private SortOrder sortOrder;
            public ListViewItemComparer()
            {
                col = 0;
                sortOrder = Windows.Forms.SortOrder.Ascending;
            }
            public ListViewItemComparer(int column)
            {
                col = column;
                sortOrder = Windows.Forms.SortOrder.Ascending;
            }
            public ListViewItemComparer(int column, SortOrder s)
            {
                col = column;
                sortOrder = s;
            }
            public int Compare(object x, object y)
            {
                if (sortOrder == Windows.Forms.SortOrder.Ascending)
                { return string.Compare(((ListViewItem)(x)).SubItems(col).Text, ((ListViewItem)(y)).SubItems(col).Text); }
                else
                { return string.Compare(((ListViewItem)(y)).SubItems(col).Text, ((ListViewItem)(x)).SubItems(col).Text); }
            }
        }

        
Ensuite, il suffit d'intercepter le clic sur les colonnes (évènement ColumnClick) et d'instancier cette classe.

          
        private void ListView1_ColumnClick(object sender, System.Windows.Forms.ColumnClickEventArgs e)
        {
            if (this.ListView1.Sorting == SortOrder.Ascending)
            { this.ListView1.Sorting = SortOrder.Descending; }
            else
            { this.ListView1.Sorting = SortOrder.Ascending; }

            this.ListView1.ListViewItemSorter = new ListViewItemComparer(e.Column, this.ListView1.Sorting);
        }

        
Remarque : j'effectue ici une comparaison de chaines, il faudra implémenter différemment si on compare des nombres par exemple.



Consultez les autres F.A.Q's


Valid XHTML 1.0 TransitionalValid CSS!

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2010 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.