Understanding WPF Grid Layout

Discussion in 'C#' started by shabbir, May 10, 2014.

  1. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,375
    Likes Received:
    388
    Trophy Points:
    83
    Grid layout is one of the most widely used layouts in any WPF application. The basic concept of a Grid is that it divides the window surface into grids of invisible rows and columns to which other controls or layouts can be added. Grids are usually invisible but can be made visible for debugging purposes. It is good practice to add only one layout or a control in one grid, however more than one grids can also be added. Importance of Grid layout can be highlighted by the fact that whenever a new WPF window is created, a Grid element is added by default in the front end XAML file. To see how Grid control actually works, let’s jump straight to the first Example of this article.

    Note: If you are totally new to WPF, this tutorial might not make much of sense to you. However, we have a beginner’s tutorial on WPF. I would recommend you to first see Absolute Beginner's Guide to WPF Application and once you have got your feet wet with the basics of WPF, you can come and carry on with this article. Let’s get started with our first example:

    Example1
    Code:
    <Window x:Class="WPFTutorial.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="300" Width="400" MinWidth="150">
        <Grid ShowGridLines="True">
            <Grid.RowDefinitions>
                <RowDefinition></RowDefinition>
                <RowDefinition></RowDefinition>
                <RowDefinition></RowDefinition>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition></ColumnDefinition>
                <ColumnDefinition></ColumnDefinition>
            </Grid.ColumnDefinitions>
        </Grid>
    </Window>
    
    This is a front end XAML file for the window. It is visible that it contains a Grid element who’s ShowGridLines attribute has been set to true. This attribute is used to show grid lines that we talked about earlier. Next, in order to add Rows, a collection of rows, Grid.RowDefinitions is used. This tells the compiler that all the elements inside it are rows. Remember this Grid.RowDefinition doesn’t specify any row it only signals that it contains rows of the Grid. Actual grid rows are added via RowDefintion elements. In Example1, three rows have been added to the Grid via three RowDefinition elements in the Grid.RowDefinition attached property.

    Similarly, to add columns to A Grid layout, two steps are needed to be performed: Firstly, the Grid.ColumnDefinition collection is required to be added which signals that all the elements inside it are Columns. Next ColumnDefinition elements are added which represents the actual columns. In Example1, two columns have been added to the Grid. The output window created using above XAML is as follows:

    Output1

    [​IMG]

    The Grid automatically divides the window into rows and columns of equal sizes as shown in the above figure and if the above figure is resized, the equality of the sizes of the columns and rows is maintained.

    Adding Controls to Grid Layout



    In Example1, it was explained that how Grid Layouts are created and how rows and columns are added to it. But that was only half of the task. Real task is to add, controls or layouts in a Grid cell. The following example demonstrates how to do this. Have a look at second example of this article:

    Example 2:
    Code:
    <Window x:Class="WPFTutorial.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="300" Width="400" MinWidth="150">
        <Grid ShowGridLines="True">
            <Grid.RowDefinitions>
                <RowDefinition></RowDefinition>
                <RowDefinition></RowDefinition>
                <RowDefinition></RowDefinition>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition></ColumnDefinition>
                <ColumnDefinition></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <Button Grid.Row="0" Grid.Column="0"> Top Left Button</Button>
            <Button Grid.Row="0" Grid.Column="1">Top Right Button</Button>
            <TextBox Grid.Row="1" Grid.Column="0">Top Left Text Box</TextBox>
            <TextBox Grid.Row="1" Grid.Column="1">Top Right Text Box</TextBox>
            
            <StackPanel Grid.Row="2" Grid.Column="0">
                <Button>Button1</Button>
                <Button>Button2</Button>
            </StackPanel>
    
            <StackPanel Grid.Row="2" Grid.Column="1">
                <Button>Button3</Button>
                <Button>Button4</Button>
            </StackPanel>
        </Grid>
    </Window>
    
    Adding controls to grids in Grid layout is a two-step process. First step is to define number of rows and columns of the grid as explained in Example1. The next step is to add controls inside the grid elements and set their attached properties Grid.Row and Grid.Column to the row and column to which you want to add the control.

    Remember, rows and columns are defined based on zero index. For instance, if you want to add a button to the first row and first column of your grid, you will set Grid.Row attached property of the button to zero and Grid.Column attached property to also zero. Similarly to add a control to 3rd row and 2nd column the Grid.Row and Grid.Column properties of the control would be 2 and 1 respectively.

    Another important thing to note is that, the size of each grid cell remains equal and doesn’t depend upon the control which it contains. The output window of the code in Example1 is shown below:

    Output:

    [​IMG]

    Setting Grid Cell Size



    In the past two examples, we have seen that Grid cells shared equals space of the window size. This behavior, however, can be altered. There are three ways to set the size of the Grid cells:
    • Absolute - The Height attribute of a grid row property can be set to absolute device independent units. For instance if the Grid has the width of 400 device-independent points and Height property of the RowDefinition element is set to 200, that Row would get half of the width of the Grid. Same is the case with the ColumnDefinition’s Width attribute.
    • Automatic - Height of a grid row or the Width of a grid column can be set to automatic which would be equal to the height or width of the control contained by that column or row. To set the Height and Width of the RowDefinition and ColumnDefinition attributes respectively, set their Height and Width to “Auto”.
    • Proportional - Empty space of the grid is divided equally between the rows and columns. To set the height and width of rows and columns, respectively their Height and Row attributes should be set to asteric “*”.
    The three aforementioned size properties can be used in combination with each other. For instance if a Grid has a height if 400 device independent points and if the height of one row is set to “200”, and there are two other rows, where the height attribute is set to “*”. The two later rows would equally get height of 100 device independent points each.

    Another important point regarding the proportional size is that its weight property can also be set. For instance If the width of one column is set to “*” and the width of second column is set to “2*”. The second column would get width, twice that of the first column.

    The next example of this tutorial explains this concept of size properties. Have a look at the next Example of this tutorial:

    Example3:
    Code:
    <Window x:Class="WPFTutorial.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="400" Width="400" MinWidth="150">
    
        <Grid ShowGridLines="True">
            <Grid.RowDefinitions>
                <RowDefinition Height="200"></RowDefinition>
                <RowDefinition Height="Auto"></RowDefinition>
                <RowDefinition Height="*"></RowDefinition>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"></ColumnDefinition>
                <ColumnDefinition Width="2*"></ColumnDefinition>
            </Grid.ColumnDefinitions>
    
            <Button Grid.Row="0" Grid.Column="0"> Top Left Button</Button>
            <Button Grid.Row="0" Grid.Column="1">Top Right Button</Button>
            <TextBox Grid.Row="1" Grid.Column="0">Top Left Text Box</TextBox>
            <TextBox Grid.Row="1" Grid.Column="1">Top Right Text Box</TextBox>
    
            <StackPanel Grid.Row="2" Grid.Column="0">
                <Button>Button1</Button>
                <Button>Button2</Button>
            </StackPanel>
    
            <StackPanel Grid.Row="2" Grid.Column="1">
                <Button>Button3</Button>
                <Button>Button4</Button>
            </StackPanel>
        </Grid>
    </Window>
    
    Example3 is a modification of the 2nd example. Here window has a height and width of 400 and since we haven’t defined the height and width for the Grid and there is only one Grid, therefore it will occupy the whole space of the window. There are three RowDefinitions with heights 200, Auto and “*” respectively. This means that the first row would take half of the height of the Grid, the second row’s height would be equal to height of the controls that it contains and the third row would occupy the remaining height.

    Similarly, there are two columns, the width of the first column is “*” and the width of the second column is “2*”. This means that first column’s width would be half of that of the second column. The output window generated through this WPF XAML file would look like this:

    Output3:

    [​IMG]

    Spanning Grid Rows and Columns



    Elements in a grid cell can span into multiple columns and rows. This is done via the Grid.RowSpan and Grid.ColumnSpan attached properties of the elements. To see how spanning rows and columns work in Grid layout, have a look at the fourth example of this tutorial:

    Example4:
    Code:
    <Window x:Class="WPFTutorial.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="400" Width="400" MinWidth="150">
    
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition ></RowDefinition>
                <RowDefinition ></RowDefinition>
                <RowDefinition ></RowDefinition>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition ></ColumnDefinition>
                <ColumnDefinition ></ColumnDefinition>
                <ColumnDefinition ></ColumnDefinition>
            </Grid.ColumnDefinitions>
          
            <Button Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2"> Top Left Button</Button>
            <Button Grid.Row="0" Grid.Column="2">Top Right Button</Button>
            <TextBox Grid.Row="1" Grid.Column="0" Grid.RowSpan="2" Background="Azure">Bottom Left Text Box</TextBox>
            <TextBox Grid.Row="1" Grid.Column="1" Grid.RowSpan="2" Grid.ColumnSpan="2" Background="Blue">Bottom Right Text Box</TextBox>
        </Grid>
    </Window>
    
    In Example4, a grid contains three rows and three columns. A button control with text “Top Left Button” is added under the row and column definitions. Closely, watch the attributes of this button element. It says that the button should be placed in the first and first column, this is done via Grid.Row=”0” and Grid.Column=”0”. Next, the attached property Grid.ColumnSpan is set to ‘2”. This means that this element should span to two columns, starting from the column mention in the Grid.Column attached property. Next another button is added to the 0th row and second column.

    After that, a text box is added that is placed in the second row and first column and it spans two rows, this means that this text box would occupy the second and third row of the first column. The last element is the text box element that starts from the second row and second column, (From the middle element) and spans two rows and two columns, which means that it occupies four cells in total. The background color property of the two text boxes is set, just to demonstrate how they actually occupy the cells.

    The output of the code in Example4 is as follows:

    Output4

    [​IMG]

    The ShowGridLines property has also been removed as you can see that no grid lines have been displayed. And as mentioned in the code, the first button has span to two columns. The second button occupies only one column and row since none of its span properties have been set. The Bottom Left Text Box has spanned to two rows starting from the second row. Finally, the the Bottom Right Text Box (Blue Background) starts from the second row and second column and spans to two rows and two columns as shown in the output.

    Splitting Windows Using GridSplitter



    The cells in a Grid layout can be split at run time using GridSplitter class. Using Grid Splitter class in a Grid layout entails understanding some basic concepts. These concepts are laid down as follows:
    • GridSplitter must be used inside a Grid element.
    • A specific column should be reserved for a GridSplitter if vertical splitting is required and in case of horizontal splitting, a specific column has to be reserved for this purpose.
    • GridSplitter should be used to split the entire row or entire column rather than a particular row or particular column.
    • If columns are being splitted, VerticalAlignment attribute should be set two stretch and HorizontalAlignment attribute should be set to center. The attribute values are reversed in case of row splitting.
    To see, how GridSpliiter can be used to split a Grid that contains two columns, have a look at the 5th Example of this article:

    Example5
    Code:
    <Window x:Class="WPFTutorial.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="400" Width="400" MinWidth="150">
    
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition ></RowDefinition>
                <RowDefinition ></RowDefinition>
                <RowDefinition ></RowDefinition>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition ></ColumnDefinition>
                <ColumnDefinition Width="Auto" ></ColumnDefinition>
                <ColumnDefinition ></ColumnDefinition>
            </Grid.ColumnDefinitions>
          
            <Button Grid.Row="0" Grid.Column="0" > Top Left Button</Button>
            <Button Grid.Row="0" Grid.Column="2">Top Right Button</Button>
            
            <TextBox Grid.Row="1" Grid.Column="0" >TopLeft Text Box</TextBox>
            <TextBox Grid.Row="1" Grid.Column="2" >Top Right Text Box</TextBox>
    
            <TextBox Grid.Row="2" Grid.Column="0" >Bottom Left Text Box</TextBox>
            <TextBox Grid.Row="2" Grid.Column="2" >Bottom Right Text Box</TextBox>
    
            <GridSplitter Grid.Row="0" Grid.Column="1" Grid.RowSpan="3" Width="10" VerticalAlignment="Stretch" HorizontalAlignment="Center">
            </GridSplitter>
        </Grid>
    </Window>
    
    Have a look at the number of columns in the Grid.ColumnDefintion element. There are three ColumnDefintion, however the middle one is reserved for the GridSplitter. Its width has been set to auto. Now, jump straight to the end of the Grid layout element. Here a GridSplitter element has been added inside the Grid layout. Pay attention to its attributes. It says that Splitting should start from the first row and 2nd column (The middle column reserved for GridSplitter). Splitting should span three rows, which means that all the rows should be split as there are three rows. The width of the splitter should be “10” device independent points. The verticalAlignment attribute is set to Stretch which means that Splitter should stretch vertically to the number of specified row spans. The HorizontalAlighnment shoud be in center of the column. The output window generated by XAML code is shown in the following figure:

    Output5

    [​IMG]

    It is shown that a splitter has appeared which can be dragged to resize the left and right columns.
     
    Last edited: Jan 21, 2017
  2. AmanBansal

    AmanBansal New Member

    Joined:
    Apr 12, 2014
    Messages:
    9
    Likes Received:
    0
    Trophy Points:
    0
    Thanks for sharing Valuable Information regarding WPF Grid ..
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice