С помощью BackgroundWorker я создал анимацию непрозрачности для некоторой формы.
Есть только одна маленькая проблема с этим подходом, но я не могу понять, в чем проблема. Скорость анимации настраивается, и даже если значение скорости очень высокое, иногда анимация очень, очень медленная, по какой-то странной причине ...
«Медленная анимация», о которой я говорю, не заикается, анимация на самом деле очень плавная, просто требуется больше времени для выполнения всей анимации (от 0% до 100% или наоборот). Это происходит только время от времени. Кажется (не уверен), что это происходит, когда компьютер выполняет какое-то другое, несколько интенсивное фоновое действие.
Конечно, мне нужно это исправить, но я также хотел бы знать, если вы все равно улучшите этот код или сделаете это по-другому и / или лучше.
Вот мой код:
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();
}