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  

Saturday, January 26, 2013

WinRT CS vs JS: Events

Without events, it is imposable for the user to interact with the program. So, for this comparison I am going to wire up a simple click event (_btnUpdateText_Click()) that changes the text on a label (_txtHelloText) with the value of an integer that counts clicks (_clickNo). The sample is mind numbly simple to make the differences as stark as possible. I am using the same names where possible in both C# and JavaScript. So here goes:

Javascript HTML

  1. Create a JavaScript Windows Store Blank App, I’m calling mine “simpleEventJS”
  2. Open up default.html and paste the following on top of the existing body tag:
    <body>
    <h1>Simple Events</h1>
    <div id="_txtHelloText">Button is still Unclicked</div>
    <button id="_btnUpdateText">Click Me</button>
    </body>
    

  3. Open js/default.js
  4. Insert the following code just above the call to app.start();:
    // Just for proofiness, I will keep track of clicks and display in the event
    var _clickNo = 0;
    
    function _btnUpdateText_Click() {
    "use strict";
    var control = document.getElementById("_txtHelloText");
    control.innerText = "Click #" + (++_clickNo);
    }
    

  5. Replace args.setPromise(WinJS.UI.processAll()); with the following code:
    args.setPromise(WinJS.UI.processAll().done(function () {
    var button1 = document.getElementById("_btnUpdateText");
    button1.addEventListener("click", _btnUpdateText_Click, false);
    })
    );
    

NOTE: On wiring the event, my first instinct would to wire it in the markup (onclick="_btnUpdateText_Click"). Experts recommend that you don’t do that, besides, if you put the event handler in js/default.js, it would be out of scope anyway. I suppose you could imbed the JavaScript in the markup, but that stinks too.

C# XAML

  1. Create a Visual Studio C# Windows Store Blank App (XAML), I’m calling mine “simpleEventCS”
  2. Open MainPage.xaml and paste the following on top of the existing Grid tag (I am using the StackPanel to get it to be more similar to the JS sample above):
    <StackPanel Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
    <TextBlock>Simple Events</TextBlock>
    <TextBlock Name="_txtHelloText">Button is still Unclicked</TextBlock>
    <Button Name="_btnUpdateText" Click="_btnUpdateText_Click">Click Me</Button>
    </StackPanel>
    

  3. Double click on “_btnUpdateText_Click” in the Button tag
  4. Right click on the highlighted text and select Navigate to Event Handler
  5. Visual Studio will open MainPage.xaml.cs and create an empty even handler named _btnUpdateText_Click, replace that handler (all the way to the first closing bracket ‘}’) with:
    // Just for proofiness, I will keep track of clicks and display in the event
    private int _clickNo = 0;
    
    private void _btnUpdateText_Click(object sender, RoutedEventArgs e)
    {
    _txtHelloText.Text = "Click #" + (++_clickNo).ToString();
    }
    

NOTE: Yes, the UI for this sample is ugly compared the JavaScript sample above; this is what I get with no styling. It would violate my brain dead simple rule.

Friday, January 25, 2013

Tiny Impressions of Windows 8

Since Microsoft gave me a really good deal on the upgrade, I’ve been running Windows 8 since late 2012. For the most part, it feels like Windows 7 without the Start Button UI element and the lack of gadgets. Other than playing with Visual Studio Express for Windows 8 and Disney’s Where’s My ???? games (free with the Windows 8 upgrade), I haven’t really touched the Windows RT side of things much. As far as I’m concerned, WinRT is really for touch and the apps are merely available to desk top users. Is this better than Apple’s approach of separating the two worlds with iOS and OS-X? Only time will tell.

I really wish Microsoft was better at helping us transaction into new design concepts. It is true that I can do everything I did in Windows 7 in 8. The bridges between the old and the new are too small and hard to find. This is really similar to when Microsoft imposed the ribbon on us in Office 2007; I know some people who are still ranting about the bloody ribbon 5 years later. The Start Screen doesn’t really bother me, it kinda reminds me of Program Manager of the old days of Windows 3; I can adjust. I just hope I’m not hearing this “Where’s my Start Button” stuff 5 years from now.

Wednesday, January 09, 2013

“Fake Store” my way of testing the transition from IsTrial Mode

Native Trial Mode is an important feature of Windows Phone 7; there are several articles about simulating being in Trial Mode. My problem was that I had a fairly complex transition between trial mode and full mode I want the premium features to show up right away without requiring the user to restart my application. So I came up with this cute little hack to simulate the session when the user buys.

App Class

Since I want to change the trial state during the running of the program, I need to have a way to re-query trial state and communicate the change of status to the rest of the program. I could query the trial mode every time I ask, but that would be bad for performance and network chatter. Notice that there is a conditional compilation symbol called FAKESTORE, the code within the #if block is only compiled if the symbol is present. Also note the presence of the DoFakeActivate() method, this is called from the Buy Now code below.

        #region Fake Store Code
public static bool IsTrial { get; private set; }

public static event EventHandler ApplicationActivated;
private void DetermineIsTrial()
{
bool armEvent = false;
bool newIsTrial = getIsTrilaFromLicenseInformation();
// I only want to fire the event when we are transitioning from
// trial to full license, I also want to have IsTrial reflect
// the current state, so I will remember to fire the event
if (!newIsTrial && IsTrial)
{
armEvent = true;
}
// Update the IsTrial status
IsTrial = newIsTrial;
// And fire the event (if necessary)
// This code will only be run once per user.
if (armEvent)
{
if (ApplicationActivated != null)
{
ApplicationActivated(new object(), EventArgs.Empty);
}
}
}
private static bool getIsTrilaFromLicenseInformation()
{
#if FAKESTORE
return !_fakeActivated;
#else
var license = new Microsoft.Phone.Marketplace.LicenseInformation();
return license.IsTrial();
#endif
}

#if FAKESTORE
private static bool _fakeActivated = false;
public void DoFakeActivate()
{
_fakeActivated = true;
DetermineIsTrial();
}
#endif
#endregion
Fake Store Code

And I need to determine if the app is in trial mode when the app is launched and activated.

// Code to execute when the application is launching (eg, from Start)
// This code will not execute when the application is reactivated
private void Application_Launching(object sender, LaunchingEventArgs e)
{
DetermineIsTrial();
}

// Code to execute when the application is activated (brought to foreground)
// This code will not execute when the application is first launched
private void Application_Activated(object sender, ActivatedEventArgs e)
{
DetermineIsTrial();
}

Normally when you buy an app using MarketplaceDetailTask, the app is re activated when the user returns from the store. Because I call DetermineIsTrial from the Application_Activted, the app will be in paid for mode when the user returns.

Buy Now Form


When I run the app in Visual Studio, I get an error message from the Store and anyway, LicenseInformation.IsTrial will always return false in Visual Studio.

        private void _btnBuyNow_Click(object sender, RoutedEventArgs e)
{
#if FAKESTORE
if (MessageBox.Show(
"Here we would send you to the app store.\n" +
"Do you want to simulate activation?",
"Fake App Store", MessageBoxButton.OKCancel)
== MessageBoxResult.OK)
{
var x = ((App)Application.Current);
x.DoFakeActivate();
}
#else
MarketplaceDetailTask marketplaceDetailTask = new MarketplaceDetailTask();
marketplaceDetailTask.Show();
#endif
}


It is necessary to call App. DoFakeActivate() to tell the App object to change the value of App.IsTrial. The user experience is radically different than normal


.fakestore_buynow


Setup Custom Configuration


I like to switch between developing / testing this part of the program and other tasks and I don’t want to have to alter actual code to change modes, so I create a custom configuration. To create a new configuration:

1. Build => Configuration Manager

2. Select <New…> from Active solution configuration:

NewConfig


3. Give it a name

4. Click OK

NewConfigName


5. Right click on the StartUp Project => select Properties

6. Select the Build tab

7. Add “;FAKESTORE” to Conditional compilation symbols


AddSymbol

Tuesday, January 01, 2013

The Geek Armando

Return of the Natives

Last week I saw Return of the Natives, a really cool improv at the Blue Door Theatre. They did a show based the Armando, a form where a monologist tells a story and then the improvisers improvise on the story, the monologist tells another story, more improv, each feeding into the other until they run out of time. In this show, the monologist was a standup comedian and she started out with a bit from her show (she now lives in LA), the improvisers where originally from Spokane but have moved away to places where they could get paid to do improv.

.NET Rocks #300 and others

In DNR # 300, Richard Campbell tells geeky tales of his early hacking as a kid in the 1970s and 80s. He told stories about how he built an Electronic Rocket Countdown Timer at 10, fixed computers for grownups, solved a difficult hardware problem by replacing the hardware, built a server farm in his house, etc. He even tells “The Goliath Story” (I can’t give it justice, just listen to it). I’ve heard Richard geek out on other podcasts on other podcasts like Hanselminutiae. I’ve heard other geeks tell tales of great geekdom on blogs, podcasts, the speaker’s room at code camps, at work, etc.

Improv in the workplace

Years ago I learned that Infusion Development offers improv classes to their associates. They even have a video on youtube. This knowledge is one of the factors that lead me to start taking improv classes at the Blue Door. Ted Neward gave an improv session at the 2012 Seattle Code Camp. There are countless articles on the business benefits of teaching improv to your employees from sites like businessweek.com, foo.com & careerbuilder.com. I’ve written about my experience with improv.

Fantasy – Putting it all together

I would like to see an Armando style show based on the monologs of a visionary/character of our industry with improvisers who are geeks. This performance could take place at an industry conference, code camp or such.

Richard Campbell would be an excellent choice to be the monologist, but there are others out there who could tell great stories. I’ve heard other geeks tell tales of great geekdom on blogs, podcasts, the speaker’s room at code camps, at work, etc. The monologist must be someone who can get up there and talk and tell good stories. There could be a dialog in the form of an interview in place of the monolog; a good interviewer can help bring out the character if the principal is otherwise shy.

Infusion Improv would be an excellent choice for the players. I hope there are other companies that offer improv training, one of those companies could send their improv all-stars or the geek improvisers from the host city. If a company provided the improvisers, they could get some recruiting PR points.