Я делал нечто подобное ранее и реализовал это с помощью GDI +.
Кнопка должна делать две вещи в своем методе рисования.
- Нарисуйте кнопку по умолчанию безотносительно к прозрачности.
- Нарисуйте изображение мышки с заданной альфа.
Используйте BackgroundWorker для плавной анимации. Таким образом, при наведении мыши запустите BackgroundWorker и заставьте его работать, пока Alpha не достигнет 1.0f. Когда мышь удалена от кнопки, рабочий должен уменьшить альфу, пока она не достигнет 0,0f. Имейте переменную с именем fadingin, чтобы BackgroundWorker понял, что он должен делать. Ваше событие ввода-вывода мыши должно просто установить для fadingin значение true или false, а затем запустить BackgroundWorker (если он еще не запущен).
Метод BackgroundWorkers DoWork может выглядеть примерно так:
void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) {
long ticks1 = 0;
long ticks2 = 0;
double interval = (double)Stopwatch.Frequency / 60;
while (true) {
ticks2 = Stopwatch.GetTimestamp();
if (ticks2 >= ticks1 + interval) {
ticks1 = Stopwatch.GetTimestamp();
if(_fadeIn){
_fadeAlpha += 0.1f;
if(_fadeAlpha > 1f){
_fadeAlpha = 1f;
break;
}
}else{
_fadeAlpha -= 0.1f;
if(_fadeAlpha < 0f){
_fadeAlpha = 0f;
break;
}
}
backgroundWorker.ReportProgress(0);
}
Thread.Sleep(1);
}
backgroundWorker.ReportProgress(0);
}
Конструкция «Секундомер» и «Цикл» приведут анимацию к анимации 60 кадров в секунду.
backgroundWorker ProgressChanged должен просто изменить ColorMatrix на правильное альфа-значение, привязать ColorMatrix к ImageAttributes и сделать элемент управления недействительным, вызвав Invalidate. Это должно быть сделано для того, чтобы перерисовка графического интерфейса запрашивалась из основного потока, а не из потока BackgroundWorker. Если вы сделаете это непосредственно из DoWork, вы получите исключение, если попытаетесь изменить ImageAttributes во время операции рисования.
Надеюсь, это поможет вам сделать хорошую плавную анимацию на кнопке.