mardi 23 avril 2013

WinForm Customized UserControl

A propos de la customisation des contrôles utilisateurs en WinForm, je tombe sur ce pauvre exemple du MSDN :

http://code.msdn.microsoft.com/CSWinFormControls-2bee4cbc

C'est un bien pauvre début. Alors j'aimerais prendre cet exemple de ComboBox à multiple colonnes pour en faire un "vrai" contrôle utilisateur.

Je prends mon VisualStudio 2010 et je créé un petit projet WindowsApplication1 et j'y ajoute un projet Class Library que j'appelle MultiColumnComboBox :
Création du projet de Class Library MultiColumnComboBox
Je peux maintenant ajouter dans mon projet de Class Library un UserControl :
Ajout d'un UserControl MultiColumnComboBox
Me voici paré pour ajouter dans ma WindowsApplication1, l'utilisation de mon nouveau contrôle MultiColumnComboBox. Je compile et je vois apparaître dans ma Toolbox mon nouveau UserControl que je vais pouvoir ajouter dans Form2 simplement en glissant déplaçant mon nouveau contrôle.

Ajout de mon nouveau contrôle MultiColumnCombox dans ma Form2
Une partie du code de l'exemple MSDN m'intéresse, il s'agit de la fonction frmCtrlCustomization_Load qui créée une DataTable pour instancier la propriété DataSource de la ComboBox.

Spécification de mon UserControl MultipleColumn ComboBox

Ce que j'aimerais pouvoir faire avec mon nouveau contrôle :
1 - Remplir la Table depuis la Form2
2 - Pouvoir ajouter autant de colonnes que je le souhaite
3 - Associer depuis la Form2 un événement qui se déclenchera sur le SelectedIndexChanged de la ComboBox de mon nouveau contrôle.
4 - Récupérer l'item sélectionné de la ComboBox afin de pouvoir l'afficher dans la Form2

1 - Remplir la Table du contrôle utilisateur depuis la Form2

Pour exposer des propriétés publiques d'un UserControl on a vu dans l'exemple zCheckBox qui faut écrire quelque chose du genre :

namespace MultiColumnComboBox
{
    public partial class MultiColumnComboBox : UserControl
    {
        private DataTable _table = new DataTable();
        [Category("MultiColumnComboBox"), Description("Table of columns."), Browsable(true)]
        public DataTable Table
        {
            get { return _table; }
            set { _table = value; }
        }

Ce qui permet ensuite dans le code de la Form2 d'écrire quelque chose du genre :

namespace WindowsFormsApplication1
{
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();

            multiColumnComboBox1.Table.Columns.Add("ID", typeof(int));
            multiColumnComboBox1.Table.Columns.Add("Name", typeof(string));
            multiColumnComboBox1.Table.Columns.Add("Surname", typeof(string));

            multiColumnComboBox1.Table.Rows.Add(1, "John", "Joe");
            multiColumnComboBox1.Table.Rows.Add(2, "Any", "Amy");
            multiColumnComboBox1.Table.Rows.Add(3, "Tony", "Smith");
            multiColumnComboBox1.Table.Rows.Add(4, "Bruce", "Willice");
            multiColumnComboBox1.Table.Rows.Add(5, "Allen", "John");
            multiColumnComboBox1.Table.Rows.Add(6, "C'est Bibi", "Coucou");

            multiColumnComboBox1.SelectedIndexChanged += new EventHandler(multiColumnComboBox1_SelectedIndexChanged);
        }

Voilà je viens de remplir les colonnes de ma ComboBox qui est devenue une Multiple ComboBox.

2 - Pouvoir ajouter autant de colonnes que l'on souhaite

La fonction qui construit la table : frmCtrlCustomization_Load devient dans mon contrôle utilisateur :

\\WindowsFormsApplication1\MultiColumnComboBox\MultiColumnComboBox.cs

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

Je remplace le 2 qui était "en dur" car la multiple combobox de l'exemple n'avait que 2 malheureuses colonnes par _table.Columns.Count afin de pouvoir créer le nombre de colonne que je souhaite.
Je vous laisse regarder les détails dans le code source à la fin de cet article.

3 - L'événement sur le SelectedIndexChanged de la ComboBox

Dans mon UserControl MultiColumnComboBox je cable un événement : comboBox1_SelectedIndexChanged et j'expose une propriété externe de mon contrôle utilisateur de la façon suivante :

namespace MultiColumnComboBox
{
    public partial class MultiColumnComboBox : UserControl
    {
        [Category("Comportement"), Description(""), Browsable(true)]
        public event EventHandler SelectedIndexChanged;

Ainsi dans ma Form2 je peux faire alors :

namespace WindowsFormsApplication1
{
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();

            multiColumnComboBox1.SelectedIndexChanged += new EventHandler(multiColumnComboBox1_SelectedIndexChanged);
        }

4 - Récupérer l'item sélectionné au niveau de la Form2

Il ne reste plus qu'à exécuter multiColumnComboBox1_SelectedIndexChanged dans l'événement SelectedIndexChanged dans mon UserControl de la façon suivante :

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            SelectedItem = (sender as ComboBox).SelectedItem;
            EventHandler handler = this.SelectedIndexChanged;
            if (handler != null)
            {
                handler(this, e);
            }
        }

Au passage je récupère l'item sélectionné dans une propriété exportée SelectedItem qui me permettra d'afficher le choix utilisateur dans la Form2. Et le tour est joué, j'ai bien un nouveau contrôle utilisateur que je pourrais utiliser de projets en projets :
Custom UserControl MultipleColumns ComboBox

Download Source Code

Customized UserControl in Winform




Aucun commentaire:

Enregistrer un commentaire