Tuesday, January 29, 2013

WinRT CS vs JS: Grids

C# XAML

In XAML, a grid is pretty straight forward. Within the Grid tag, you define the rows and column in RowDefinitions and ColumnDefinitions tags. Below the definitions, you place the controls that will reside in the Grid, you assign them to cells and control cell spans with Row. attributes.

<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
    <Grid.RowDefinitions>
        <RowDefinition Height="1*"/>
        <RowDefinition Height="1*"/>
        <RowDefinition Height="1*"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="1*"/>
        <ColumnDefinition Width="1*"/>
        <ColumnDefinition Width="1*"/>
    </Grid.ColumnDefinitions>
    <TextBlock Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3">Title</TextBlock>
    <TextBlock Grid.Row="1" Grid.Column="0">2, 1</TextBlock>
    <TextBlock Grid.Row="1" Grid.Column="1">2, 2</TextBlock>
    <TextBlock Grid.Row="1" Grid.Column="2">2, 3</TextBlock>
    <TextBlock Grid.Row="2" Grid.Column="0">3, 1</TextBlock>
    <TextBlock Grid.Row="2" Grid.Column="1">3, 2</TextBlock>
    <TextBlock Grid.Row="2" Grid.Column="2">3, 3</TextBlock>
</Grid>

This is straight forward; the WinJS examples will attempt to match this layout.

JavaScript HTML


In WinJS, a grid is achieved using an IE 10 specific version of the CSS Grid Layout. Since this is CSS, you can select HTML elements using id or class selectors, you can even use inline styles. In this example, I will mix in all three. Basically you:

Create a style for the grid, in that style you need to tell it to display as a grid with a display attribute with the value -ms-grid.

Define the columns with a -ms-grid-columns property (“1fr” means 1 fraction value, behaves like 1* in XAML, see table below).

Define the rows with a -ms-grid-rows property.

You can assign an HTML element to a row with a -ms-grid-row and to a column with a -ms-grid-column. I have been playing with the idea of creating a class for each row and column/

With this in mind, I created the following CSS (put in css/default.css, if you want to do this yourself):

#MainGrid {
    display: -ms-grid;
    -ms-grid-columns: 1fr 1fr 1fr;
    -ms-grid-rows: 1fr 1fr 1fr;
    height: 100%; /* make it big, so we can see it */
}
.Col01 {
    -ms-grid-column: 1;
}
.Col02 {
    -ms-grid-column: 2;
}
.Col03 {
    -ms-grid-column: 3;
}
.Row01 {
    -ms-grid-row: 1;
}
.Row02 {
    -ms-grid-row: 2;
}
.Row03 {
    -ms-grid-row: 3;
}

OK, so you have some styles, but you can’t see styles. You need some HTML markup to receive the styles.

At this early stage in my WInJS development, it makes sense to me to style the main grid using an ID selector, so I’m calling the main grid div “MainGrid”. Each grid is going to be unique.

For row and column assignment I am using the ColXX and RowXX classes. To me is as easy to read as XAML’s Grid.Row=”0” and you can avoid creating ids for every cell in every cell in your application.

And I’m using the inline style on the first row to force it to span the 3 columns. I was debating using a class called “ColSpan03” but this gave me the opportunity to demonstrate an inline style.

With all this in mind, here’s the HTML for my grid (put in the body of default.html, if you are playing along at home):

<div id="MainGrid" >
    <div class="Col01 Row01" style="-ms-grid-column-span: 3">Title</div>
    <div class="Col01 Row02">2, 1</div>
    <div class="Col02 Row02">2, 2</div>
    <div class="Col03 Row02">2, 3</div>
    <div class="Col01 Row03">3, 1</div>
    <div class="Col02 Row03">3, 2</div>
    <div class="Col03 Row03">3, 3</div>
</div>

Comparing units in Row and Column Definitions


Here is a list of the various units that can be used to define the sized of rows and columns.


Purpose XAML WinJS Notes
Fractional Units * so 1 fractional unit would be “1*”, 2 would be 2* and so on fr so 1 fractional unit would be “1fr”, 2 would be “2fr” and so on  
Auto Sizing “auto” “auto” Although they are the same keyword, they behave slightly differently,
WinJS is more willing to wrap text and XAML is more likely to scroll
Percent Not supported % so fifty percent would be “50%” For XAML, you could use Fractional Units that add up to 100
Pixels Just the number, so 20 pixels would be “20” px, so 20 pixels would be 20px  
Inches Not supported in  
Centimeters Not supported cm  
Millimeters Not supported mm  
Points Not supported pt  

No comments: