-
Notifications
You must be signed in to change notification settings - Fork 29
Description
The rendering of the NoItemText property, or similar outputs (ie, no table model, no column model) is broken due to the way that calls to Invalidate() are filtered in the out OnHorizontalScroll handler.
The paint code for NoItemText always attempts to paint the text in the center of the client rectangle of the control, that is, it's always supposed to be center, irrespective of scroll position. Hint number 1 that something is broken is that in a control that has wide enough columns to have a horizontal scrollbar, the text moves with the 'background' of the control.
If you shrink the window down, and then scroll such that some portion of text ends up off screen, it never repaints correctly when the text comes back on screen. Usually, the background is white, or contains 'stuttering' paints.
The OnPaint handler is definitely trying to repaint the text every time its called, and it's definitely being called whenever scrolling happens - the problem is that the control is double buffered and our Invalidate() filtering logic is a little too overzealous. Since we're double buffered, the .Net code that handles the double buffering never copies from our painted-to buffer for this portions of the UI, because we never invalidate it.
Here is the current implementation of the scroll handler - note, that it does not have any handling for invalidating the region where we're painting the NoItemText:
protected void OnHorizontalScroll( object sender, ScrollEventArgs e )
{
// stop editing as the editor doesn't move while
// the table scrolls
if( this.IsEditing )
{
this.StopEditing();
}
if( this.CanRaiseEvents )
{
// non-solid row lines develop artifacts while scrolling
// with the thumb so we invalidate the table once thumb
// scrolling has finished to make them look nice again
if( e.Type == ScrollEventType.ThumbPosition )
{
if( this.GridLineStyle != GridLineStyle.Solid )
{
if( this.GridLines == GridLines.Rows || this.GridLines == GridLines.Both )
{
this.Invalidate( this.CellDataRect, false );
}
}
// same with the focus rect
if( this.FocusedCell != CellPos.Empty )
{
this.Invalidate( this.CellRect( this.FocusedCell ), false );
}
}
else
{
this.HorizontalScroll( e.NewValue );
}
}
}
If you replace that method with the following (hereforth called "The Cheap Fix"), it works:
protected void OnHorizontalScroll( object sender, ScrollEventArgs e )
{
// stop editing as the editor doesn't move while
// the table scrolls
if( this.IsEditing )
{
this.StopEditing();
}
if( this.CanRaiseEvents )
{
this.Invalidate( this.CellDataRect, false );
if( e.Type != ScrollEventType.ThumbPosition )
{
this.HorizontalScroll( e.NewValue );
}
}
}
I've attached a video of the broken behavior and a video showing the behavior with The Cheap Fix: