bool IEquatable <BufferedPaintTransition <TState> > .Equals(BufferedPaintTransition <TState> other) { return(Object.Equals(this.FromState, other.FromState) && Object.Equals(this.ToState, other.ToState)); }
void Control_Paint(object sender, PaintEventArgs e) { if (BufferedPaintSupported && Enabled) { bool stateChanged = !Object.Equals(_currentState, _newState); IntPtr hdc = e.Graphics.GetHdc(); if (hdc != IntPtr.Zero) { // see if this paint was generated by a soft-fade animation if (!Interop.BufferedPaintRenderAnimation(Control.Handle, hdc)) { Interop.BP_ANIMATIONPARAMS animParams = new Interop.BP_ANIMATIONPARAMS(); animParams.cbSize = Marshal.SizeOf(animParams); animParams.style = Interop.BP_ANIMATIONSTYLE.BPAS_LINEAR; // get appropriate animation time depending on state transition (or 0 if unchanged) animParams.dwDuration = 0; if (stateChanged) { BufferedPaintTransition <TState> transition = Transitions.Where(x => Object.Equals(x.FromState, _currentState) && Object.Equals(x.ToState, _newState)).SingleOrDefault(); animParams.dwDuration = (transition != null) ? transition.Duration : DefaultDuration; } Rectangle rc = Control.ClientRectangle; IntPtr hdcFrom, hdcTo; IntPtr hbpAnimation = Interop.BeginBufferedAnimation(Control.Handle, hdc, ref rc, Interop.BP_BUFFERFORMAT.BPBF_COMPATIBLEBITMAP, IntPtr.Zero, ref animParams, out hdcFrom, out hdcTo); if (hbpAnimation != IntPtr.Zero) { if (hdcFrom != IntPtr.Zero) { using (Graphics g = Graphics.FromHdc(hdcFrom)) { OnPaintVisualState(new BufferedPaintEventArgs <TState>(_currentState, g)); } } if (hdcTo != IntPtr.Zero) { using (Graphics g = Graphics.FromHdc(hdcTo)) { OnPaintVisualState(new BufferedPaintEventArgs <TState>(_newState, g)); } } _currentState = _newState; Interop.EndBufferedAnimation(hbpAnimation, true); } else { OnPaintVisualState(new BufferedPaintEventArgs <TState>(_currentState, e.Graphics)); } } e.Graphics.ReleaseHdc(hdc); } } else { // buffered painting not supported, just paint using the current state _currentState = _newState; OnPaintVisualState(new BufferedPaintEventArgs <TState>(_currentState, e.Graphics)); } }