New to Telerik UI for WinForms? Download free 30-day trial

Auto-size entire row height.

It is common to use the rows auto-size functionality when the cells have multi-line text. However by default the grid measures only the visible cells text. So when the users scrolls horizontally the row height might be adjusted dynamically. This article will explain how you can measure the entire row so the row height is constant while the users are scrolling horizontally.

Create custom row element.

In order to return the proper rows height to the grid you need to create a custom row element. Then you should override the MeasureOverride method. You need this method in order to measure all cells not just the visual ones. Then you can return the proper height. In order to speed the measure process, you can check the height only of the cells that are not visible.

Sample implementation for the custom row element.

public class CustomRowElement : GridDataRowElement
{
    protected override Type ThemeEffectiveType
    {
        get
        {
            return typeof(GridDataRowElement);
        }
    }
    protected override SizeF MeasureOverride(SizeF availableSize)
    {
        SizeF baseSize = base.MeasureOverride(availableSize);
        CellElementProvider provider = new CellElementProvider(this.TableElement);
        SizeF desiredSize = SizeF.Empty;
        foreach (GridViewColumn column in this.ViewTemplate.Columns)
        {
            if (!this.IsColumnVisible(column))
            {
                continue;
            }
            GridDataCellElement cellElement = provider.GetElement(column, this) as GridDataCellElement;
            this.Children.Add(cellElement);
            if (cellElement != null)
            {
                cellElement.Measure(new SizeF(column.Width, float.PositiveInfinity));
                if (desiredSize.Height < cellElement.DesiredSize.Height)
                {
                    desiredSize.Height = cellElement.DesiredSize.Height;
                }
            }
            cellElement.Detach();
            this.Children.Remove(cellElement);
        }
        SizeF elementSize = this.TableElement.RowScroller.ElementProvider.GetElementSize(this.RowInfo);
        int oldHeight = RowInfo.Height == -1 ? (int)elementSize.Height : RowInfo.Height;
        this.RowInfo.SuspendPropertyNotifications();
        this.RowInfo.Height = (int)desiredSize.Height;
        this.RowInfo.ResumePropertyNotifications();
        if (!this.RowInfo.IsPinned)
        {
            int delta = RowInfo.Height - oldHeight;
            TableElement.RowScroller.UpdateScrollRange(TableElement.RowScroller.Scrollbar.Maximum + delta, false);
        }
        baseSize.Height = this.RowInfo.Height;
        return baseSize;
    }
    private bool IsColumnVisible(GridViewColumn column)
    {
        return column.IsVisible;
    }
}

Public Class CustomRowElement
    Inherits GridDataRowElement
    Protected Overrides ReadOnly Property ThemeEffectiveType() As Type
        Get
            Return GetType(GridDataRowElement)
        End Get
    End Property
    Protected Overrides Function MeasureOverride(ByVal availableSize As SizeF) As SizeF
        Dim baseSize As SizeF = MyBase.MeasureOverride(availableSize)
        Dim provider As New CellElementProvider(Me.TableElement)
        Dim desiredSize As SizeF = SizeF.Empty
        For Each column As GridViewColumn In Me.ViewTemplate.Columns
            If Not Me.IsColumnVisible(column) Then
                Continue For
            End If
            Dim cellElement As GridDataCellElement = TryCast(provider.GetElement(column, Me), GridDataCellElement)
            Me.Children.Add(cellElement)
            If cellElement IsNot Nothing Then
                cellElement.Measure(New SizeF(column.Width, Single.PositiveInfinity))
                If desiredSize.Height < cellElement.DesiredSize.Height Then
                    desiredSize.Height = cellElement.DesiredSize.Height
                End If
            End If
            cellElement.Detach()
            Me.Children.Remove(cellElement)
        Next column
        Dim elementSize As SizeF = Me.TableElement.RowScroller.ElementProvider.GetElementSize(Me.RowInfo)
        Dim oldHeight As Integer = If(RowInfo.Height = -1, CInt(elementSize.Height), RowInfo.Height)
        Me.RowInfo.SuspendPropertyNotifications()
        Me.RowInfo.Height = CInt(desiredSize.Height)
        Me.RowInfo.ResumePropertyNotifications()
        If Not Me.RowInfo.IsPinned Then
            Dim delta As Integer = RowInfo.Height - oldHeight
            TableElement.RowScroller.UpdateScrollRange(TableElement.RowScroller.Scrollbar.Maximum + delta, False)
        End If
        baseSize.Height = Me.RowInfo.Height
        Return baseSize
    End Function
    Private Function IsColumnVisible(ByVal column As GridViewColumn) As Boolean
        Return column.IsVisible
    End Function
End Class

Using the custom row element.

The final step is to replace the default row elements. This can be achieved in the CreateRow event handler.

void radGridView1_CreateRow(object sender, GridViewCreateRowEventArgs e)
{
    if (e.RowType == typeof(GridDataRowElement))
    {
        e.RowType = typeof(CustomRowElement);
    }
}

Private Sub radGridView1_CreateRow(ByVal sender As Object, ByVal e As GridViewCreateRowEventArgs)
    If e.RowType Is GetType(GridDataRowElement) Then
        e.RowType = GetType(CustomRowElement)
    End If
End Sub

A complete solution which adds cached height is available in our SDK repository.

In this article