Je souhaite colorer la propriété BackColor
d'un PictureBox
lorsque la souris y entre.Windows Forms MouseEnter ne se déclenche pas après le déplacement du contrôle
Je transforme le BackColor
en jaune lorsque l'événement MouseEnter
se déclenche, et je réinitialise à transparent dans MouseLeave
.
Puis quand je clique sur un PictureBox
, je change de position, donc j'ai aussi un événement Move
qui le réinitialise en transparent.
Le problème est, une fois que je l'ai déplacé, j'ai besoin d'entrer deux fois le PictureBox
avec la souris pour déclencher l'événement MouseEnter!
C'est un problème très graphique, donc j'ai téléchargé un peu video pour vous montrer ce qui se passe, il va sûrement expliquer mon problème mieux que moi.
J'ai essayé d'une autre manière, en changeant la couleur pas dans MouseEnter
mais dans MouseHover
. Dans ce cas, cela fonctionne bien, sauf que j'ai un retard de 500ms avant de déclencher l'événement Move, ce qui n'est évidemment pas ce que je veux.
Je n'ai pas de solution viable pour le moment.
Pour le code, il est très simple, pour le moment je:
private void pictureBoxMouseUp(object sender, MouseEventArgs e)
{
// I move the PictureBox here
}
private void pictureBoxMove(object sender, EventArgs e)
{
(sender as PictureBox).BackColor = Color.Transparent;
}
private void pictureBoxMouseEnter(object sender, MouseEventArgs e)
{
(sender as PictureBox).BackColor = Color.LightYellow;
}
private void pictureBoxMouseLeave(object sender, MouseEventArgs e)
{
(sender as PictureBox).BackColor = Color.Transparent;
}
Dans le Designer.cs, mes événements pour chaque PictureBox sont comme:
this.pictureBox2.MouseDown += new System.Windows.Forms.MouseEventHandler(this.pictureBoxMouseDown);
this.pictureBox2.MouseEnter += new System.EventHandler(this.pictureBoxMouseEnter);
this.pictureBox2.MouseLeave += new System.EventHandler(this.pictureBoxMouseLeave);
this.pictureBox2.MouseUp += new System.Windows.Forms.MouseEventHandler(this.pictureBoxMouseUp);
this.pictureBox2.Move += new System.EventHandler(this.pictureBoxMove);
EDIT: Pour répondre à ma question, c'est le code que j'utilise maintenant: (les commentaires sont en français)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Diagnostics;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using EmoTEDTherapeute;
namespace ControlSceneImage {
public class SceneImage : PictureBox {
public static readonly int defaultWidth = 100;
public static readonly int defaultHeight = 100;
static readonly int activePbPosY; // Position en Y des scènes actives
static readonly Dictionary<string, Point> scenesPos = null; // Invariant, stocke la position initiale des PictureBox
static readonly List<Point>[] activeScenesPos = null; // Invariant, stocke les positions des PictureBox en fonction du nombre de scènes actives
static List<SceneImage> activeScenes = null;
const int maxActiveScenes = 5;
const int ecart = 80;
const int decalage = 15;
const int panelScenesWidth = 909;
const int panelScenesHeight = 154;
const int panelScenesLocationX = 35;
const int panelScenesLocationY = 36;
bool isActive;
static SceneImage() {
// Constructeur initialisant tous les membres statiques, n'est appelé qu'une seule fois, avant tout le reste
activePbPosY = (panelScenesLocationY + panelScenesHeight - (int)(0.6 * defaultHeight))/2;
scenesPos = new Dictionary<string, Point>();
activeScenesPos = new List<Point>[maxActiveScenes];
for (int i = 0; i < maxActiveScenes; i++) {
activeScenesPos[i] = CalcActiveScenesPos(i+1);
}
activeScenes = new List<SceneImage>();
}
public SceneImage() {
MouseEnter += new EventHandler(OnMouseEnter);
MouseDown += new MouseEventHandler(OnMouseDown);
MouseUp += new MouseEventHandler(OnMouseUp);
MouseLeave += new EventHandler(OnMouseLeave);
BorderStyle = BorderStyle.FixedSingle;
Size = new Size(defaultWidth, defaultHeight);
SizeMode = PictureBoxSizeMode.Zoom;
isActive = false;
}
private static List<Point> CalcActiveScenesPos(int nbActiveScenes) {
List<Point> ret = new List<Point>();
for (int i = 0; i < nbActiveScenes; i++) {
ret.Add(new Point((panelScenesLocationX + panelScenesWidth + ecart)/2 + (int)((ecart + defaultWidth) * (i - nbActiveScenes/2.0)) + decalage, activePbPosY));
}
return ret;
}
private void UpdateScenesPos() {
for(int i = 0; i < activeScenes.Count; i++) {
activeScenes[i].Location = activeScenesPos[activeScenes.Count - 1][i];
}
}
private void OnMouseEnter(object sender, EventArgs e) {
BackColor = Color.LightYellow;
Cursor = Cursors.Hand;
}
private void OnMouseDown(object sender, MouseEventArgs e) {
BorderStyle = BorderStyle.Fixed3D;
}
private void OnMouseUp(object sender, MouseEventArgs e) {
if (!scenesPos.ContainsKey(Name)) {
// Si ce n'est pas déjà fait, on stocke la position initiale de notre PictureBox
scenesPos.Add(Name, Location);
// Et on crée un Panel vide sous elle
Panel panel = new Panel();
panel.Location = Location;
panel.Size = Size;
panel.BorderStyle = BorderStyle.Fixed3D;
// On ajoute notre panel à notre form
Form1.AddInSeance(panel);
}
if (!isActive) {
activeScenes.Add(this);
} else {
Location = scenesPos[Name];
activeScenes.Remove(this);
}
isActive = !isActive;
UpdateScenesPos();
}
private void OnMouseLeave(object sender, EventArgs e) {
BorderStyle = BorderStyle.FixedSingle;
BackColor = Color.Transparent;
}
}
}
J'utilise la même méthode que précédemment, et f ou une raison inconnue, maintenant cela fonctionne. Merci à vous tous pour m'aider :)
J'ai écrit un « bonjour tout le monde » au-dessus de mon message, mais il semble qu'il a été coupé quand je poste pour certains raison étrange, même lorsque je l'ai édité, alors ne soyez pas impoli :) –
pouvez-vous s'il vous plaît fournir plus de code pour montrer quels événements vous avez assigné à vos gestionnaires? –
Peut-être que cela a à voir avec certaines parties focales. – kevintjuh93