Avec l'aide de BackgroundWorker, j'ai créé une animation d'opacité pour une forme quelconque.Animation d'opacité de formulaire en C# avec un BackgroundWorker
Il y a seulement un petit problème avec cette approche mais je ne peux pas comprendre où est le problème. La vitesse d'animation est configurable et même si la valeur de la vitesse est très élevée, parfois les animations sont très, très lentes, pour une raison étrange ...
La "slow animation" dont je parle n'est pas bégayante, la l'animation est en fait très douce, il faut juste plus de temps pour réaliser l'animation entière (de 0% à 100%, ou vice versa). Cela arrive seulement de temps en temps. Il semble (pas sûr) que cela se produise lorsque l'ordinateur effectue une autre action de fond, quelque peu intensive.
Je dois corriger cela bien sûr mais j'aimerais aussi savoir s'il y a moyen d'améliorer ce code ou si vous le feriez différemment et/ou mieux.
Voici mon code:
private const int TOGGLE_EFFECT_SPEED = 10;
private void blendWorker_DoWork(object sender, DoWorkEventArgs e) {
bool blendIn = (bool)e.Argument;
// Loop through all opacity values
for(double value = 1; value <= 100; value += 1) {
// Report the current progress on the worker
blendWorker.ReportProgress(0, blendIn ? value : 100 - value);
// Suspends the current thread by the specified blend speed
System.Threading.Thread.Sleep(11 - TOGGLE_EFFECT_SPEED);
}
// Set the worker result as the inverse tag value
e.Result = !blendIn;
}
private void blendWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) {
double opValue = (double)e.UserState;
// Show and repaint the whole main notes window?
if(opValue == 1.0) {
Show();
Invalidate(true);
}
// Set the main notes window opacity value
Opacity = (double)e.UserState/100;
}
private void blendWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
bool tagFlag = (bool)e.Result;
// Hide the main notes window?
if(tagFlag) {
Hide();
}
// Set the main notes window tag value
Tag = tagFlag;
}
/*
THE FOLLOWING METHOD IS PART OF A DIFFERENT CLASS.
ACTUALLY, IT'S THE "PROGRAM" CLASS WHERE MAIN()
IS LOCATED. THIS METHOD IS CALLED TO SHOW/HIDE
THE MAIN APPLICATION FORM WITH AN OPACITY ANIMATION
*/
internal static void ToggleNotesWindow() {
// Get the tag value converted to boolean type
bool tagFlag = Convert.ToBoolean(NotesWindow.Tag, CultureInfo.InvariantCulture);
// Bring the main notes window to front?
if(tagFlag) Program.NotesWindow.BringToFront();
// Run the blend effect if it's not already running
if(!NotesWindow.blendWorker.IsBusy) {
NotesWindow.blendWorker.RunWorkerAsync(tagFlag);
}
// Activate and focus the main notes window?
if(tagFlag) Program.NotesWindow.Activate();
}
Je ne pense pas que ce soit correct car je vois clairement une différence de vitesse de fondu entre TOGGLE_EFFECT_SPEED = 1 (sleep (10)) et TOGGLE_EFFECT_SPEED = 10 (sleep (1)). Et je vois aussi une différence entre ces deux avec une valeur entre 1 et 10. Et je ne pense pas que vous ayez ce que je voulais dire par "lent" parce que la valeur de vitesse n'a pas d'importance, le problème que j'ai est sans vitesse changement de valeur. –
Vous ne verrez pas beaucoup de différence entre les valeurs de vitesse de 1 et 10 puisque le programmateur de threads ne dort pas pendant moins de 10 ms dans la plupart des cas - ils apparaîtront donc à la même vitesse. La chose qui aura le plus d'effet est la lenteur de la fenêtre et des fenêtres. –