Powered by MSDN

US - English
NEW! Silverlight 5 is available Learn More

DataGrid Row Auto-Resize only grows row height but won'... RSS

27 replies

Last post Jan 21, 2012 02:34 PM by snelldl

(0)
  • dgonth

    dgonth

    Member

    4 Points

    4 Posts

    DataGrid Row Auto-Resize only grows row height but won't shrink

    Feb 06, 2009 07:51 PM | LINK

    Using the latest December 2008 release of the DataGrid. 

    When dynamically adding and removing items from a list embedded in a cell with autosize enabled for the row height there appears to be a bug in the DataGrid.  The DataGrid row will increase its height properly when items are added to the embedded list but the row height never decreases when the cell height shrinks after items are removed.  In my situation I am using an embedded ListBox but this appears to be a general problem anytime the row content height changes dynamically.

    Extra Details

    ------------------ 

    I took a look at the DataGrid source code released recently at

    http://www.microsoft.com/downloads/details.aspx?FamilyID=EB83ED4C-AC85-4DE9-8395-285628EE2254&displaylang=en

    I traced this behavior to a line in the MeasureOverride method of the DataGridCellsPresenter class.

    if (autoSizeHeight)
    {
       this.DesiredHeight = Math.Max(this.DesiredHeight, cell.DesiredSize.Height);
    }

    Because this.DesiredHeight is never reset the row always stays at the max height it has seen.

     It looks like this.DesiredHeight should have been reset to 0 up above in the method in order to get the row to shrink properly when the content changes.  I'm not sure if this wouldn't break something else but it did fix the problem in the version of the DataGrid I had the source for.  (Unfortunately I don't believe this is the source for the Dec 2008 version of the DataGrid.  The older version still has some nasty bugs having to do with using popups while editing a cell that make it unusable for my app.) See the this.DesiredHeight=0 setting in the code snippet below for the resizing fix.Code snippet: DataGridCellsPresenter.cs
    protected override Size MeasureOverride(Size availableSize)
    {
      if (this.OwningGrid == null)
      {
        return base.MeasureOverride(availableSize);
      }
      
      bool autoSizeHeight;
      double measureHeight;
      
      if (double.IsNaN(this.OwningGrid.RowHeight))
      {
         // No explicit height values were set so we can autosize
         autoSizeHeight = true;
         measureHeight = double.PositiveInfinity;
         this.DesiredHeight = 0; // dgonth - Bug fix to autosize correctly.
       }
       else
       {
          this.DesiredHeight = this.OwningGrid.RowHeight;
          measureHeight = this.DesiredHeight;
          autoSizeHeight = false;
       }
    
     

    datagrid DataGrid Row Auto Resizing

  • rich_r26

    rich_r26

    Member

    27 Points

    102 Posts

    Re: DataGrid Row Auto-Resize only grows row height but won't shrink

    Aug 28, 2009 02:25 AM | LINK

    I'm using Silverlight 3. And having similar problem. I have a Control for the column's DataTemplate. And its parts could collaps and visible, then collaps again. After it becomes visible the row height increases but does not shrink after it collapsed. Is there solution for it? Thanks!

  • praveenrangarajan

    praveenranga...

    Member

    42 Points

    14 Posts

    Re: DataGrid Row Auto-Resize only grows row height but won't shrink

    Aug 28, 2009 06:55 PM | LINK

    I faced this problem a long time back in SL2 and have since used this solution (works well with SL3 also) implement a IValueConverter for the Height with the function returning "0" or "Auto" depending on the bitflag. Let me explain. I have a property (int) that indicates the state of the Visibility (0 Collapsed, 1 Visible). The IValueConverter routine returns "0" if 0 and "Auto" if 1. This solution works perfectly. Let me know if you have the same success or need more help. Praveen
  • rich_r26

    rich_r26

    Member

    27 Points

    102 Posts

    Re: DataGrid Row Auto-Resize only grows row height but won't shrink

    Aug 29, 2009 01:46 PM | LINK

    I am not sure if I am following you. I have single column DataGrid, make it simple it is something like:

     <data:DataGrid.Columns>
                                    <data:DataGridTemplateColumn >
                                        <data:DataGridTemplateColumn.CellTemplate>
                                            <DataTemplate  >                                           
                                                <local:MyControl Height="Auto"
                                                    VerticalAlignment="Stretch" HorizontalAlignment="Left"                                               
                                                    VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" />
                                            </DataTemplate>
                                        </data:DataGridTemplateColumn.CellTemplate>                               
                                    </data:DataGridTemplateColumn>

    In MyControl it has a few parts, someone collapsed.

    <Border x:Name="theContainer">
    <StackPanel>
            <Button x:Name="ShowHidePart2" Content="Click"/>
            <TextBlock x:Name="part1" Text="some text..." Height="100"/>
            <TextBlock x:Name="CollapeAndVisual_part2" Text="...show...hide..." Height="200" />
           
    </StackPanel>
    </Border>

    The button ShowHidePart2 will control to show CollapeAndVisual_part2.
    When uncollapse and collapse again, the DataGridRow's height does not
    shrink and leaves some blank space.
    In your solution where do you apply the IValueConverter? (I'm not sure what is the return 0 about).
    And at what time is the best time to apply it? After click on the button when is the definit time
    that the un-collapse or collapse is complete and the visual has its size re-setted? Strange is I saw the part2
    collapsed and uncollapsed, but did not get SizeChanged on the "theContainer". 

  • rusmo27

    rusmo27

    Member

    9 Points

    14 Posts

    Re: Re: DataGrid Row Auto-Resize only grows row height but won't shrink

    Sep 02, 2009 12:27 PM | LINK

    I'm having a similar problem getting a Grid Row to resize based on the visibility of one of its content's controls. Looking forward to a solution. Thanks, Will.
  • BKrishna

    BKrishna

    Member

    112 Points

    70 Posts

    Re: Re: Re: DataGrid Row Auto-Resize only grows row height but won't shrink

    Oct 05, 2009 11:44 AM | LINK

    Did anyone find a solution to this? I have a expander control in my datagrid and I am facing same problem.

    Praveen, Can you pls ellobrate of the solution that you discussed? 

  • estern

    estern

    Participant

    1614 Points

    357 Posts

    Re: Re: Re: Re: DataGrid Row Auto-Resize only grows row height but won't shrink

    Oct 11, 2009 09:00 PM | LINK

    in the xaml near the top add

        <UserControl.Resources>
            <local:dgPlanRowHeight  x:Key="dgPlanRowHeight" />

    in the xaml for the grid definition add

    RowHeight="{Binding Converter={StaticResource dgPlanRowHeight}, Path=EXPANDED}"

    note:  EXPANDED is a column in the class bound to the grid

    In code

    Public Class dgPlanRowHeight
        Implements IValueConverter
        Public Function Convert(ByVal value As Object, _
                    ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.Convert

            Dim bExpanded As Boolean = value
            If bExpanded Then
                Return "Auto"
            Else
                Return "20"
            End If
        End Function

        Public Function ConvertBack(ByVal value As Object, _
                    ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.ConvertBack
            Return Nothing ' use the default
        End Function

    End Class 

     

  • robmaransky

    robmaransky

    Member

    24 Points

    34 Posts

    Re: Re: Re: Re: DataGrid Row Auto-Resize only grows row height but won't shrink

    Oct 15, 2009 09:59 PM | LINK

    I have been unable to make this solution work for me. Has anyone out there been able to work around this problem in Silverlight 3? I can't believe this issue still exists. The DataGrid is a key component in most business applications and this is not an obscure use case. Any time your CellEditTemplate is larger than your CellTemplate, you will see this issue. Can anyone at Microsoft hear us?

     Is there a fix out there that I am unaware of?

  • estern

    estern

    Participant

    1614 Points

    357 Posts

    Re: Re: Re: Re: Re: DataGrid Row Auto-Resize only grows row height but won't shrink

    Oct 19, 2009 03:15 PM | LINK

    I did some more work on this

    1 - subclass the grid

    Partial Public Class MyDataGrid

    Inherits DataGrid

    Public GridRow As List(Of DataGridRow) = New List(Of DataGridRow) '

    End Class

    2 - track when you add / remove rows

    XAML 

    <local:MyDataGrid x:Name="dgPlan"

    LoadingRow="dgPlan_LoadingRow" UnloadingRow="dgPlan_UnloadingRow"

     

    VB 

    Private Sub dgPlan_LoadingRow(ByVal sender As System.Object, ByVal e As System.Windows.Controls.DataGridRowEventArgs)

    If m_Expanded Then

    e.Row.DataContext.expanded = True

    Else

    e.Row.DataContext.expanded = False

    End If

    dgPlan.GridRow.Add(e.Row)

    ' set height here based on condition 

    e.Row.Height = 20

    End Sub

     

    Private Sub dgPlan_UnloadingRow(ByVal sender As System.Object, ByVal e As System.Windows.Controls.DataGridRowEventArgs)

    dgPlan.GridRow.Remove(e.Row)

    End Sub

    or set height later - button click (button is in the row in the grid) in this case

    Private Sub cmdEC_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)

    Dim lIndex As Long

    Dim cmdButton As Object = CType(e.OriginalSource, Button).DataContext()

    lIndex = m_oPlanList.IndexOf(cmdButton)

    Dim aRow As DataGridRow

    aRow = dgPlan.GridRow(lIndex)

    Dim aPlan As WorkView.PlanSupportServiceReference1.clsPlan

    lIndex = m_oPlanList.IndexOf(cmdButton)

    aPlan = m_oPlanList(lIndex)

    If aPlan.Expanded Then

    aPlan.Expanded = False

    aRow.Height = 25

    else

    aPlan.Expanded = True

    aRow.Height = 200

    End if

  • estern

    estern

    Participant

    1614 Points

    357 Posts

    Re: Re: Re: Re: Re: Re: DataGrid Row Auto-Resize only grows row height but won't shrink

    Nov 01, 2009 11:33 PM | LINK

    here's a simple solution

    background

    dgPlan.itemssource = observable collection of clsPlan

    XAML

                        <data:DataGrid x:Name="dgPlan"
                                LoadingRow="dgPlan_LoadingRow" 
    Code

         ' set the row binding for the row height converter
        Private Sub dgPlan_LoadingRow(ByVal sender As System.Object, ByVal e As System.Windows.Controls.DataGridRowEventArgs)

            ' create a row level binding - works for height or background row color or ...
            Dim aBinding As New Binding("Expanded")
            aBinding.ConverterParameter = e.Row.DataContext
            aBinding.Mode = BindingMode.OneWay


            Dim aHeightConverter As New dgPlanRowHeightConverter
            aBinding.Converter = aHeightConverter

            aBinding.ValidatesOnExceptions = True
            e.Row.SetBinding(DataGridRow.HeightProperty, aBinding)
        End Sub

    Converter

    Public Class dgPlanRowHeightConverter
        Implements IValueConverter

        Public Function Convert(ByVal value As Object, _
                    ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.Convert

            Dim aPlan As clsPlan = parameter

            If aPlan.Expanded Then
                Return aPlan.SomeVar * 20
            Else
                Return 20
            End If

        End Function

        Public Function ConvertBack(ByVal value As Object, _
                    ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.ConvertBack
            Return Nothing ' not implemented
        End Function

    End Class

    Notes

            Dim aBinding As New Binding("Expanded")
    Expanded is a member of clsPlan.  It raises a notifypropertychanged event.  Binding to Expanded causes the converter to fire if expanded is changed anywhere.

            aBinding.ConverterParameter = e.Row.DataContext
    The class bound to the row is passed to the converter as the "parameter".  The converter can now access anything in the class but still respond to a notifypropertychanged event.