Tuesday, November 11, 2008

Drag and Drop avec WinForm c#

Je fais un petit article, alors que je cherche a faire du drag and drop dans une application WinForm.
J'ai déjà souvent du Drag and drop , mais la technique n'est pas forcement évidente pour
commencer a Dragger un élement.
Je fais aussi mon article pour pense bête.

Pour commencer un element pour dragger un élement, il faut determiner le moment
d'appeller la méthode :
DoDragDrop(object obj,DragDropEffects);

C'est une image que je souhaite déplacer par cette technique.
Alors j'ajoute une variable a la Classe private bool mbClic = false.
Puis je gére cette variable pour qu'elle reflète l'état de ma souris , pour savoir sur l'utilisateur a cliquer sur mon control.

Puis à l'événement :
private void xxxxxx_MouseMove(object sender, MouseEventArgs e)
{
if (mIsClic) { DoDragDrop(mesdonnées, DragDropEffects.Move); }
}

Ainsi voila votre élément est draggable .
Apres il faut que le control accepte le Drag and Drop, et il y a un evenement qui permet de
savoir si l'element qui veut etre dragger est acceptable

private void xxxxx_DragOver(object sender, DragEventArgs e)

Pour savoir si le type est bon :

e.Data.GetDataPresent(DataFormats.FileDrop)

pour savoir si c'est un fichier venant de l'explorateur.

La difficulté est de connaitre le DataFormat parfois.

Il y a une chose qui peux vous aider et moi m'a enduit en erreur.
C'est à propos de l'événement :

DragEventArgs et surtout ces valeurs X et Y qui sont absolue.

Il faut utilise la méthode PointToClient(new Point(e.X, e.Y)) du control
sur lequel le Drop a été effectué.

Ainsi vous pourrez réaliser un drag ans drop sur les éléments d'un même controle FlowLayout par exemple et vous baser sur ces coordonnées modifié pour déplacer le control drag parmi les autres:

Voici la method pour deplacer un control dans in FlowLayout apres drag and drop sur le meme FlowLayout.

private void MoveInFlowLayout(Control
cToMove , Point pt)
{
int index = -1;
// Trouve l'index du control contenant le point x,y
foreach (Control c in FlowLayoutPanel.Controls)
{
if (
(c.Location.Y < pt.Y && c.Location.X < pt.X)
&&
(c.Location.Y + c.Height > pt.Y && c.Location.X + c.Width > pt.X)
)
{
index =
FlowLayoutPanel.Controls.IndexOf(c);
}
}

/// Dropper sur un zone vide alors on le deplace a la fin des éléments.
if (index == -1)
{
FlowLayoutPanel.Controls.SetChildIndex(
cToMove,
FlowLayoutPanel.Controls.Count
);
}
else
{
// On l'insere a l'endroit du control trouvé.
FlowLayoutPanel.Controls.SetChildIndex(
cToMove, index);
}
}




No comments: