Search code examples
c#silverlightgridcode-behindscrollviewer

Scrollviewbox is giving more space than I would like


I have a scroll viewbox defined as such:

<ScrollViewer Width="150" Height="150" HorizontalScrollBarVisibility="Auto">
   <Grid Name="RootElement">
   </Grid>
</ScrollViewer>

And in codebehind I populate the grid 'RootElement' with even more grids,

  void CreateGrid(uint _Columns, uint _Rows)
  {
     Grid layoutRoot = GetTemplateChild( "RootElement" ) as Grid;
     Random rand = new Random( );

     for(int r = 0; r < _Rows; r++)
     {
        layoutRoot.RowDefinitions.Add( new System.Windows.Controls.RowDefinition( ) { Height = new GridLength( 50, GridUnitType.Pixel ) } );
        for(int c = 0; c < _Columns; c++)
        {
           layoutRoot.ColumnDefinitions.Add( new System.Windows.Controls.ColumnDefinition( ) { Width = new GridLength( 50, GridUnitType.Pixel ) } );

           var border = new Border( );
           Grid.SetColumn( border, c );
           Grid.SetRow( border, r );

           Color col = new Color();
           col.A = (byte)rand.Next(255);
           col.R = (byte)rand.Next(255);
           col.G = (byte)rand.Next(255);
           col.B = (byte)rand.Next(255);
           border.Background = new SolidColorBrush( col );
           border.BorderBrush = new SolidColorBrush( Color.FromArgb( 0xff, 0x33, 0x33, 0x33 ) );

           layoutRoot.Children.Add( border );
        }
     }
  }

Now my problem is if I create, say, 10x10 grids inside the root grid (e.g., CreateGrid(10,10)) I end up with a tonne of white space to the right of the scroll view area. The white space seems to increase exponentially as the number of grid cells I create increases. Vertically it's fine, scaled perfectly normally, but horizontally there's a massive gap. Maybe only 5% of the horizontal space is populated by the grids.

How can I make it so that the scrollviewer will only cover the space of the grids inside it?


Solution

  • That happens because you have your layoutRoot.ColumnDefinitions.Add() inside the inner loop. For 10 columns and 10 rows, you end up creating 10 columns for every 1 row, for a total of 100 columns and 10 rows.

    Iterate over rows and columns separately to create the column/row definitions first. Then do the nested loops to create the controls.

    for(int r = 0; r < _Rows; r++) {
        layoutRoot.RowDefinitions.Add( new System.Windows.Controls.RowDefinition( ) { Height = new GridLength( 50, GridUnitType.Pixel ) } );
    }
    
    for(int c = 0; c < _Columns; c++) {
        layoutRoot.ColumnDefinitions.Add( new System.Windows.Controls.ColumnDefinition( ) { Width = new GridLength( 50, GridUnitType.Pixel ) } );
    }
    
    for(int r = 0; r < _Rows; r++) {
        for(int c = 0; c < _Columns; c++) {
            var border = new Border( );
            ...
        }
    }