J'ai un formulaire qui affiche la file d'attente des messages et le nombre de ces messages peuvent être modifiés. Vraiment, je veux faire clignoter l'étiquette (longueur de la file d'attente) lorsque le nombre de messages a été augmenté pour améliorer la convivialité des formulaires. Devrais-je mettre en œuvre un contrôle personnalisé et utiliser un thread ou un minuteur supplémentaire pour changer la couleur de l'étiquette? Quelqu'un at-il implémenté une telle fonctionnalité? Quelle est la meilleure solution (moins de ressources et moins de dégradation des performances) à implémenter de manière comportementale?
SOLUTION:
Composant de formulaire avec minuterie pouvant limiter le nombre d'animations par seconde et implémenter l'effet de fondu en sortie pour la couleur d'arrière-plan du contrôle externe.
Vous pouvez créer un composant et des événements personnalisés pour commencer à clignoter. Je pense que c'est une bonne solution. Clignotant, vous pouvez mettre en œuvre avec minuterie.
Ce qui suit clignote en utilisant async
et await
private async void Blink(){
while (true){
await Task.Delay(500);
label1.BackColor = label1.BackColor == Color.Red ? Color.Green : Color.Red;
}
}
Timer timer = new Timer();
timer.Interval = 500;
timer.Enabled = false;
timer.Start();
if( messagesNum > oldMessagesNum)
timer.Tick += new EventHandler( timer_Tick );
else
timer.Tick -= timer_Tick;
void timer_Tick( object sender, EventArgs e )
{
if(messageLabel.BackColor == Color.Black)
messageLabel.BackColor = Color.Red;
else
messageLabel.BackColor = Color.Black;
}
Voici une implémentation assez simple qui fonctionnerait dans votre formulaire. Vous pouvez également créer un contrôle personnalisé avec le même code et lancer simplement Timer.Start()
dans une méthode pour ce contrôle.
Je sais que c’est un article très ancien, mais tous ceux qui recherchent quelque chose d’un peu plus polyvalent que les solutions booléennes postées peuvent tirer parti des éléments suivants:
using System.Diagnostics;
using System.Threading.Tasks;
private async void SoftBlink(Control ctrl, Color c1, Color c2, short CycleTime_ms, bool BkClr)
{
var sw = new Stopwatch(); sw.Start();
short halfCycle = (short)Math.Round(CycleTime_ms * 0.5);
while (true)
{
await Task.Delay(1);
var n = sw.ElapsedMilliseconds % CycleTime_ms;
var per = (double)Math.Abs(n - halfCycle) / halfCycle;
var red = (short)Math.Round((c2.R - c1.R) * per) + c1.R;
var grn = (short)Math.Round((c2.G - c1.G) * per) + c1.G;
var blw = (short)Math.Round((c2.B - c1.B) * per) + c1.B;
var clr = Color.FromArgb(red, grn, blw);
if (BkClr) ctrl.BackColor = clr; else ctrl.ForeColor = clr;
}
}
Que vous pouvez appeler comme tel:
SoftBlink(lblWarning, Color.FromArgb(30, 30, 30), Color.Red,2000,false);
SoftBlink(lblSoftBlink, Color.FromArgb(30, 30, 30), Color.Green, 2000,true);
Pouvez-vous utiliser un .gif
animé à la place (peut-être comme arrière-plan du nombre)? cela ferait ressembler les pages Web de la vieille école, mais cela pourrait fonctionner.
Créez votre propre UserControl
pour celui-ci, celui qui hérite de Label
au lieu de Control
directement. Ajoutez une méthode StartBlinking
dans laquelle vous démarrez un objet Timer
dont l'événement tick modifie le style de l'étiquette (en modifiant les propriétés BackgroundColor et ForegroundColor à chaque fois pour créer l'effet de clignotement).
Vous pouvez également ajouter une méthode StopBlinking
pour l'éteindre ou laisser votre Timer
s'arrêter après 5 secondes, peut-être.
Vous pouvez utiliser la classe Timer
ici. Voici ce que j'ai mis en œuvre. La couleur de l'étiquette clignote sur l'événement Button_click.
//click event on the button to change the color of the label
public void buttonColor_Click(object sender, EventArgs e)
{
Timer timer = new Timer();
timer.Interval = 500;// Timer with 500 milliseconds
timer.Enabled = false;
timer.Start();
timer.Tick += new EventHandler(timer_Tick);
}
void timer_Tick(object sender, EventArgs e)
{
//label text changes from 'Not Connected' to 'Verifying'
if (labelFirst.BackColor == Color.Red)
{
labelFirst.BackColor = Color.Green;
labelFirst.Text = "Verifying";
}
//label text changes from 'Verifying' to 'Connected'
else if (labelFirst.BackColor == Color.Green)
{
labelFirst.BackColor = Color.Green;
labelFirst.Text = "Connected";
}
//initial Condition (will execute)
else
{
labelFirst.BackColor = Color.Red;
labelFirst.Text = "Not Connected";
}
}