public class FlashControl : Control { private Image _image; private System.Threading.Timer _timer; private static readonly int Interval = 100; private bool _stop = true; private bool _flashIn = true; private float _opaque; private float _step = 0.02f; private bool _exit = false; private bool _firstTime = true; public FlashControl() { SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.ResizeRedraw | ControlStyles.OptimizedDoubleBuffer, true); } [DefaultValue(null)] public Image Image { get { return _image; } set { if (!_stop) { return; } _image = value; if (DesignMode) { Invalidate(); } } } [DefaultValue(0.02f)] public float Step { get { return _step; } set { if (!_stop) { return; } if (value < 0) { _step = 0.01f; } else if (value > 1) { _step = 1f; } else { _step = value; } } } /// <summary> /// 淡入淡出效果是否执行完毕 /// </summary> [Browsable(false)] public bool FlashEnded { get { return _exit; } } private System.Threading.Timer Timer { get { if (_timer == null) { _timer = new System.Threading.Timer( new System.Threading.TimerCallback(Animate), null, -1, Interval); } return _timer; } } protected override void OnPaint(PaintEventArgs pe) { //base.OnPaint(pe); if (!DesignMode) { AnimateDraw(pe.Graphics, _opaque); } else if (DesignMode) { if (_image != null) { pe.Graphics.DrawImage(_image, new Rectangle(0, 0, _image.Width, _image.Height)); } } } private void AnimateDraw(Graphics g, float op) { if (_image == null) { return; } float[][] matrix = new float[][]{ new float[]{1,0,0,0,0}, new float[]{0,1,0,0,0}, new float[]{0,0,1,0,0}, new float[]{0,0,0,op,0}, new float[]{0,0,0,0,1}}; ImageAttributes attributes = new ImageAttributes(); ColorMatrix colorMatrix = new ColorMatrix(matrix); int width = _image.Width; int height = _image.Height; attributes.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); g.DrawImage(_image, new Rectangle(0, 0, width, height), 0, 0, width, height, GraphicsUnit.Pixel, attributes); } private void Animate(object obj) { _exit = false; if (_flashIn) { _opaque += _step; if (_opaque > 1) { _opaque = 1f; _exit = true; } } else { _opaque -= _step; if (_opaque < 0) { _opaque = 0f; _exit = true; Hide(); } } Invalidate(); if (_exit) { _timer.Change(-1, Interval); _stop = true; } } private delegate void InvokeDelegate(); private new void Hide() { if (this.InvokeRequired) { InvokeDelegate invokeDelegate = new InvokeDelegate(Hide); this.Invoke(invokeDelegate); } else { this.Visible = false; } } public void FlashIn() { if (!_stop && !_exit && !_firstTime) { return; } _stop = false; _flashIn = true; _firstTime = false; _opaque = _flashIn ? 0f : 1f; Timer.Change(0, Interval); } public void StopFlash() { if (!_stop && !_exit && !_firstTime) { Timer.Change(-1, Interval); _stop = true; _firstTime = false; } } public void FlashOut() { if (!_stop && !_exit && !_firstTime) { return; } _stop = false; _flashIn = false; _firstTime = false; _opaque = _flashIn ? 0f : 1f; Timer.Change(0, Interval); } protected override Size DefaultSize { get { return new Size(200, 200); } } protected override void Dispose(bool disposing) { base.Dispose(disposing); if (disposing) { if (_timer != null) { _timer.Dispose(); _timer = null; } if (_image != null) { _image.Dispose(); _image = null; } } } }