Drag drop entrant et clipboard : même combat !

Description

Le drag and drop permet d'améliorer de façon considérable un interface utilisateur. Cependant, le drag and drop n'est pas seulement interne à un appli, il peut aussi être externe. Un tas de cellules sélectionnées dans Excel par exemple peut très bien attérir sur votre appli. A vous de savoir si vous voulez les gérer ou non.

La récupération des données envoyées lors d'un drag and drop est assez simple. L'application qui fournit les infos peut les envoyer sous plusieurs formes. Par exemple, Excel envoie ses cellules déplacées sous forme d'un XML, de texte, d'image... Il est alors possible de récupérer ces formats (sous la forme d'un tableau de strings), et de dire si oui ou non on peut accepter le drag and drop. Cette opération se fait alors que la souris survole la zone de notre appli, et que le drag and drop n'est pas effectué.

Un fois le drop effectué, c'est à dire quand l'utilisateur termine le drag and drop, on cherche alors à récupérer les données.

Pour vous aider à gérer votre drag and drop entrant, je vous propose cette source. Si vous voulez gérer les infos en provenance d'Excel, par exemple, utiliser mon appli pour y droper des données Excel. Vous pourrez alors voir tous les types de données envoyés par exel, et la plupart du temps leur contenu.

Dans le titre, je parle du presse-papier (clipboard) pour la bonne et simple raison que la donnée y est gérée de la même manière. On récupère un objet implémentant l'interface IDataObject, sur lequel on récupère les formats de données dispos, puis les infos en elles même.

Source / Exemple :


using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Xml;

namespace DragDropIn {
	public partial class Form1 : Form {
		/// <summary>
		/// Variable permettant de stocker les données envoyées à notre programme par drag and drop.
		/// </summary>
		private Hashtable Data;

		/// <summary>
		/// Cet évènement survient lorsque la souris arrive sur notre formulaire lors d'une
		/// opération de drag and drop.
		/// On demande alors à l'évènement e (DragEventArgs) quels sont les types de données
		/// que l'on peut récupérer, et on les liste dans le listview de la form.
		/// </summary>
		private void Form1_DragEnter(object sender, DragEventArgs e) {
            ListFormats(e.Data);
            e.Effect = DragDropEffects.All;
		}

		/// <summary>
		/// Cet évènement survient à la fin de l'opération de drag and drop, lorsque la souris est "relachée"
		/// sur notre formulaire.
		/// On récupère alors tous les type des données que l'on a stocké dans notre list view, 
		/// on demande à l'objet e (DragEventArgs) tous les objets possibles, et on
		/// les stocke dans un hash table.
		/// </summary>
		private void Form1_DragDrop(object sender, DragEventArgs e) {
            GetAllData(e.Data);
		}

		/// <summary>
		/// Lorsque l'on clique sur un élément de la liste des types envoyés par le drag and drop,
		/// on affiche l'objet correspondant.
		/// L'objet est affiché dans un propertygrid, et quand c'est possible dans une zone
		/// de texte ou dans un zone d'image.
		/// </summary>
		private void listBox1_SelectedIndexChanged(object sender, EventArgs e) {
			ResetUI();
			try {
				this.propertyGrid1.SelectedObject = Data[this.listBox1.SelectedItem.ToString()];
				
				if(this.propertyGrid1.SelectedObject.GetType() == typeof(Bitmap)) {
					this.pictureBox1.Image = (Bitmap) this.propertyGrid1.SelectedObject;
				}

				if(this.propertyGrid1.SelectedObject.GetType() == typeof(string)) {
					this.textBox1.Text = (string) this.propertyGrid1.SelectedObject;
				}

				if(this.propertyGrid1.SelectedObject.GetType() == typeof(System.IO.MemoryStream)) {
					System.IO.StreamReader reader = new System.IO.StreamReader((System.IO.MemoryStream) this.propertyGrid1.SelectedObject);
					this.textBox1.Text = (string) reader.ReadToEnd();
				}

				if(this.propertyGrid1.SelectedObject.GetType() == typeof(XmlDocument)) {
					this.textBox1.Text = ((XmlDocument) this.propertyGrid1.SelectedObject).InnerXml;
				}
			} catch { }
		}

		/// <summary>
		/// Méthode permettant de réinitialiser la zone de visualisation d'image et de texte.
		/// </summary>
		private void ResetUI() {
			this.pictureBox1.Image = null;
			this.textBox1.Text = string.Empty;
		}

		/// <summary>
		/// Lorsqu'un nouvel objet est chargé dans le propertygrid, on en affiche le type
		/// au bas de la form.
		/// </summary>
		private void propertyGrid1_SelectedObjectsChanged(object sender, EventArgs e) {
			this.toolStripStatusLabel1.Text = "L'objet en cours de visualisation est de type : " + this.propertyGrid1.SelectedObject.GetType().ToString();
		}

		/// <summary>
		/// Constructeur du formulaire.
		/// </summary>
		public Form1() {
			InitializeComponent();
		}

        /// <summary>
        /// Survient lorsque l'utilisateur souhaite consulter le contenu du presse-papier.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            ListFormats(Clipboard.GetDataObject());
            GetAllData(Clipboard.GetDataObject());
        }

        /// <summary>
        /// Permet de lister les formats disponibles dans l'objet Data.
        /// </summary>
        /// <param name="data"></param>
        private void ListFormats(IDataObject data)
        {
            ResetUI();
            this.listBox1.Items.Clear();
            string[] formats = data.GetFormats();

            foreach (string s in formats)
            {
                this.listBox1.Items.Add(s);
            }
        }

        /// <summary>
        /// Permet de récupérer toutes les données stockées dans l'objet Data.
        /// </summary>
        /// <param name="data"></param>
        private void GetAllData(IDataObject data)
        {
            ResetUI();
            Data = new Hashtable();
            foreach (string key in this.listBox1.Items)
            {
                Data.Add(key, data.GetData(key));
            }
        }
	}
}

Conclusion :


- Je posterais certainement une source sur le drag and drop sortant et l'implémentation de l'interface IDataObject.
- Cette source est en .net 2

Codes Sources

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.