Usercontrol : edition de listview

Contenu du snippet

Cet usercontrol est une listview qui réagit un peu près comme celles des fenêtres "Watch" du mode debug de Visual Studio.

Source / Exemple :


using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;

namespace UserControls
{
	/// <summary>
	/// Summary description for UserControlEditList.
	/// </summary>
	public class UserControlEditList : System.Windows.Forms.UserControl
	{
		/// <summary> 
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.Container components = null;
		private System.Windows.Forms.ColumnHeader columnHeader1;

		private bool editingItem;
		private bool elementIsUnique;
		private bool supprSpacesExt;
		private System.Windows.Forms.ListView listViewStock;
		private SortOrder sorted;
		private IButtonControl acceptButton;

		public UserControlEditList()
		{
			// This call is required by the Windows.Forms Form Designer.
			InitializeComponent();

			// initialise les valeurs de l'usercontrol
			// initialise les valeurs de la liste
			InitializeList(false, false, SortOrder.None);
		}

		//ce constructeur peut etre appelé si on veut spécifié:
		//														-l'unicité des éléments de la liste
		//														-La suppression des espaces sur les bords
		//														-Le fait que la liste soit rangée automatiquement

		public UserControlEditList(bool Unique, bool SupprSpacesExt, SortOrder sortOrder)
		{
			// This call is required by the Windows.Forms Form Designer.
			InitializeComponent();

			// initialise les valeurs de l'usercontrol
			// initialise les valeurs de la liste
			InitializeList(Unique, SupprSpacesExt, sortOrder);		
		}

		/// <summary> 
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if(components != null)
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Component Designer generated code
		/// <summary> 
		/// Required method for Designer support - do not modify 
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.listViewStock = new System.Windows.Forms.ListView();
			this.columnHeader1 = new System.Windows.Forms.ColumnHeader();
			this.SuspendLayout();
			// 
			// listViewStock
			// 
			this.listViewStock.AllowDrop = true;
			this.listViewStock.AutoArrange = false;
			this.listViewStock.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
																							this.columnHeader1});
			this.listViewStock.Dock = System.Windows.Forms.DockStyle.Fill;
			this.listViewStock.FullRowSelect = true;
			this.listViewStock.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None;
			this.listViewStock.LabelEdit = true;
			this.listViewStock.Location = new System.Drawing.Point(0, 0);
			this.listViewStock.Name = "listViewStock";
			this.listViewStock.Size = new System.Drawing.Size(500, 500);
			this.listViewStock.TabIndex = 0;
			this.listViewStock.View = System.Windows.Forms.View.Details;
			this.listViewStock.KeyDown += new System.Windows.Forms.KeyEventHandler(this.listView_KeyDown);
			this.listViewStock.AfterLabelEdit += new System.Windows.Forms.LabelEditEventHandler(this.listView_AfterLabelEdit);
			this.listViewStock.BeforeLabelEdit += new System.Windows.Forms.LabelEditEventHandler(this.listView_BeforeLabelEdit);
			// 
			// columnHeader1
			// 
			this.columnHeader1.Text = "Col1";
			this.columnHeader1.Width = 143;
			// 
			// UserControlEditList
			// 
			this.Controls.Add(this.listViewStock);
			this.Name = "UserControlEditList";
			this.Size = new System.Drawing.Size(500, 500);
			this.SizeChanged += new System.EventHandler(this.UserControlEditList_SizeChanged);
			this.Enter += new System.EventHandler(this.UserControlEditList_Enter);
			this.Leave += new System.EventHandler(this.UserControlEditList_Leave);
			this.ResumeLayout(false);

		}
		#endregion

		private void InitializeList(bool Unique, bool SupprSpacesExt, SortOrder sortOrder)
		{
			editingItem = false;
			//créé un champ vide pour pouvoir etre editer
			listViewStock.Items.Add("");
			//met la longueur de la colonne égale a celle de la liste
			listViewStock.Columns[0].Width = listViewStock.Width - 4;
			//détermine si on doit controler le fait que chaque élément doit être unique
			elementIsUnique = Unique;
			//détermine si on doit enlever les espaces extérieures
			supprSpacesExt = SupprSpacesExt;
			sorted = sortOrder;
		}

		private void SelectItemList(int index, bool enable)
		{
			listViewStock.Items[index].Selected = enable;
			listViewStock.Items[index].Focused = enable;
			if (enable)
				listViewStock.Items[index].EnsureVisible();
		}

		public ListView listView
		{
			get{return listViewStock;}
			set{listViewStock = value;}
		}

		public int Count
		{
			get{return listViewStock.Items.Count - 1;}		
		}

		private void listView_BeforeLabelEdit(object sender, System.Windows.Forms.LabelEditEventArgs e)
		{
			editingItem = true;
		}

		private void listView_AfterLabelEdit(object sender, System.Windows.Forms.LabelEditEventArgs e)
		{
			editingItem = false;
			listViewStock.SuspendLayout();

			string editedText = e.Label;
			//si aucune edition n a été faite
			if (e.Label == null)
				return;
			//si l'option suppression des espaces est gérée
			if (supprSpacesExt)
			{
				editedText = e.Label.TrimStart(' ').TrimEnd(' ');
			}
			//si le champ est vide a la fin de l edition
			if (editedText != null && editedText != "")
			{
				//si l option element unique est prise en compte
				if (elementIsUnique)
				{
					//on compare le nouvel élément aux éléments existants
					for (int index = 0; index < listViewStock.Items.Count - 1; index++)
					{
						if (editedText == listViewStock.Items[index].Text)
						{
							e.CancelEdit = true;
							return;
						}
					}
				}
				if (e.Item == listViewStock.Items.Count - 1)
				{
					//on ajoute un champ vide a la fin(pour prochaine edition)
					listViewStock.Items.Add("");
				}			
				//on met le focus/selection sur le prochain élément
				SelectItemList(e.Item + 1, true);
				SelectItemList(e.Item, false);

				//on efface l emplacement du nouvel element
				listViewStock.Items[e.Item].Remove();
				int indexInsert = e.Item;
				//si l on doit ordonner les elements
				if (sorted != SortOrder.None)
				{
					if (sorted == SortOrder.Ascending)
					{
						for (indexInsert = 0; editedText.CompareTo(listViewStock.Items[indexInsert].Text) > 0 && indexInsert < listViewStock.Items.Count - 1; indexInsert++);
					}
					else
						if (sorted == SortOrder.Descending)
					{
						for (indexInsert = 0; editedText.CompareTo(listViewStock.Items[indexInsert].Text) < 0 && indexInsert < listViewStock.Items.Count - 1; indexInsert++);
					}
				}	
				//on insere l'élément
				listViewStock.Items.Insert(indexInsert, editedText);

			}
			else
			{
				if (e.Item < listViewStock.Items.Count - 1)
				{	
					//on annule l'action de l edition
					e.CancelEdit = true;
					//on supprime l'item
					listViewStock.Items.RemoveAt(e.Item);
				}
			}
			e.CancelEdit = true;
			listViewStock.ResumeLayout();
		}

		private void listView_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
		{
			//si la liste n est pas en etat édition
			if (editingItem == false)
			{
				//si l utilisateur tape Ctrl + A
				if (e.KeyCode == Keys.A && e.Control == true) 
				{
					// on sélectionne tous les éléments
					for (int index = 0; index < listViewStock.Items.Count; index++)
						listViewStock.Items[index].Selected = true;
				
				}
				//si la touche entrée est actionnée
				if (e.KeyCode == Keys.Enter)
				{
					//si un seul champ est sélectionné
					if (listViewStock.SelectedItems.Count == 1)
					{
						//on edite celui ci
						listViewStock.SelectedItems[0].BeginEdit();
					}
				}
				// si la touche suprimer est actionnée
				if (e.KeyCode == Keys.Delete)
				{
					//tant qu il reste des champs sélectionnés
					if (listViewStock.SelectedItems.Count != 0)
					{
						//on récupère l index du premier element sélectionné (pour la fin)
						int itemToSelect = listViewStock.SelectedItems[0].Index;
						while (listViewStock.SelectedItems.Count != 0)
						{
							//si le champ sélectionné n'est pas le dernier élément de la liste
							if (listViewStock.SelectedItems[0].Index != listViewStock.Items.Count - 1)
							{
								//on efface le premier des champs sélectionnés
								listViewStock.Items[listViewStock.SelectedItems[0].Index].Remove();
							}
							else
							{
								//on déselectionne
								listViewStock.Items[listViewStock.SelectedItems[0].Index].Selected = false;
							}
						}
						// on sélectionne l'élément dont la position est identique au premier élément supprimé 
						SelectItemList(itemToSelect, true);
					}				
				}
			}		
		}

		private void UserControlEditList_SizeChanged(object sender, System.EventArgs e)
		{
			SuspendLayout();
			//met la colonne a la meme longueur que la liste
			this.columnHeader1.Width = listViewStock.Size.Width - 4;
			ResumeLayout();
		}

		private void UserControlEditList_Enter(object sender, System.EventArgs e)
		{
			//permet d utiliser la touche entrée sans se soucier de l AcceptButon de la form
			acceptButton = ParentForm.AcceptButton;
			ParentForm.AcceptButton = null;
		}

		private void UserControlEditList_Leave(object sender, System.EventArgs e)
		{
			//retablie la propritee acceptbouton dans la form
			ParentForm.AcceptButton = acceptButton;
		}
	}
}

Conclusion :


dernier ajout de code : le 01 juillet 2004

version du 01 juillet 2004 :
-longueur du champ en sélection fixé
-changement de nature de la liste (détail)
-fix du bogue lors de réduction du controle
-possibilité d'entrer des options dans constructeur du controle:
.unicité des éléments(non par défaut)
.suppression des espaces sur les bords(non par défaut)
.possibilité d'ordonner les éléments(pas d'ordre par défaut)
- ajouts d'indexeur pour acceder a list(listView) et le nombre d'items(Count)
- Inhibation des boutons par défaut de la form
- Changement du namespace (celui d avant ne ressemblait a rien)

version du 30 juin 2004 :
-fix du bogue de delete de dernier élément
-sélection d'élément suivant automatique après édition

N.B :
- Il n y'a dans la source qu un UserControl. Vous devez l'insérer dans une form
pour que ça puisse fonctionner.

bogues:
-le controle n'est pas/est mal géré lorsque on veut une liste plus grande que part défaut(1000, 1000)

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.