Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rendering of NoItemsText is broken when hscrolling due to overzealous filtering of Invalidate() #41

Open
antiduh opened this issue Mar 3, 2017 · 1 comment

Comments

@antiduh
Copy link
Contributor

antiduh commented Mar 3, 2017

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:

XPTable NoItemsText.zip

@antiduh
Copy link
Contributor Author

antiduh commented Mar 3, 2017

The more complicated fix would to extract the logic from OnPaintEmptyTableText() to know when the NoItemsText needs to be painted, then use that logic in both OnPaintEmptyTableText() and OnHoritizontalScroll()'s invalidation logic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant