Wednesday, September 28, 2011

Windows 8 Secondary Tiles

In the past couple posts I have showed various ways of manipulating the start menu tile for an application. Besides manipulating the main tile your app can also create secondary tiles when the user wants to see more information then can easily be displayed on a single tile. You can see an example of this in the Weather app. Open the app and add a second city, right click to bring up the app bar and click Pin City. Once you do this a second tile will appear on the start screen with the information for that city. Let’s look at how you create a secondary tile.
Before you can create a secondary tile you need, at a minimum, a 150x150 pixel image for the tile. Create the image and save it as a .PNG file in your applications Images directory then add it to the application in solution explorer. Set the Build Action property on the image to Content, and the Copy to Output Directory property to “Copy if Newer” or “Copy Always”. Once you have the image you can use the following code to display it:
Note: You will want to include the Windows.UI.StartScreen namespace in your file.

async public void ShowSecondayTile() 
{
  Uri logo = new Uri("ms-resource:images/SecondayLogo.png");
  SecondaryTile secondaryTile = new SecondaryTile("MySecondaryTile1",
    "Secondary Tile",
    "Hello World Secondary",
    "Tile 1 activated",
    TileDisplayAttributes.ShowName,
    logo);
  bool isPinned = await secondaryTile.RequestCreateAsync();
}

First we need to create a Uri object to point to the tile image we added to the images folder. Next we create the secondary tile object. The parameters passed to the constructor mostly correspond to the properties you set in the manifest for the default startup tile.

  • - tileId: Since you can create more the one secondary tile the tileId uniquely identifies the tile to your application. If you add more then one tile with the tileId the later one will replace the earlier.


  • - shortName: A name that is displayed on the tile if you set the ShowName attribute.


  • - displayName: The name displayed when you hover over the tile.


  • - arguments: A string that you want passed back to your application when the tile is clicked. We will talk more about this later.


  • - displayAttributes: Any attributes you need to set on the tile, for example ShowName.


  • - logoRefernce: Uri of the image to use for the square tile.

Besides the properties you set in the constructor there are also properties on the object for setting things like the WideLogo, SmallLogo, ForegroundText, etc.

Once you have the SecondaryTile object setup the last line requests the creation of the tile. When that line is executed the user will see a popup that looks like this:

clip_image001

This shows an image of the tile, gives the user a chance to change the shortName and has a button to accept the request. If the user accepts, the function will return a true. If they click off the popup the request will be denied and the function will return a false.

One interesting thing to note in this line is the “await” keyword. Await, along with async in the function declaration are new keywords in C# that are used to handle asynchronous functions and you will see these used a lot in Windows 8 Metro applications. The details of how these work are beyond the scope of this article, but in short, execution will not continue to the next line until RequestCreateAsync is complete, but unlike in synchronous programming it won’t block the UI thread either. Essentially the ShowSecondayTile function is suspended until the async function completes.

Once the secondary tile is displayed the user can remove it from the start menu by right clicking it and selecting Remove from the app bar. We can also have our application request the removal of a secondary tile with this code:

async private void RemoveSecondaryTile() 
{
    var secondaryTile = new SecondaryTile(“MySecondaryTile1”);
    bool isDeleted = await secondaryTile.RequestDeleteAsync();
}

The first line creates a SecondaryTile object based on the tileId we set when we created the tile, and the second line requests the removal. The removal works just like the creation where the user will be prompted if they want to remove it and the functional will return true of false based on what the user chooses to do.

When the user clicks on a secondary tile, Windows will launch your application just as if they had clicked on the main tile. To determine which secondary tile launched the app you can use the Arguments property on SecondaryTile object. In your application’s App.xaml.cs file you will see the following default code:

protected override void OnLaunched(LaunchActivatedEventArgs args) 
{
    Window.Current.Content = new MainPage();
    Window.Current.Activate();
}

The LaunchActivatedEventArgs object contains a string property called Arguments that will contain the contents of the Arguments property we set on the secondary tile. One way to handle this would be to modify the MainPage contructor to accept a LaunchActivatedEventArgs object as a parameter and then modify the OnLaunched event to pass args to MainPage. In the MainPage constructor you can then get the Arguments property and handle it as needed.

While digging a little deeper into secondary tiles I noticed that both the TileUpdateManager and BadgeUpdateManager have methods to create updaters for secondary tile. For badges you call use a line like this to get a secondary tile updater:

var tileUpdater = TileUpdateManager.CreateTileUpdaterForSecondaryTile(“MySecondaryTile1”)

where the parameter passed is the tileId of the secondary tile. This updater would then allow us to show badges on the tile. We should be able to do something similar for notifications but I always got an exception when I called CreateTileUpdaterForSecondayTile(“MySecondaryTile1”) . Not sure if I am doing something wrong or if this is a bug.

Monday, September 26, 2011

Windows 8 Metro Tile Badges

In my last post I showed how to make notifications appear on an application’s start menu tile. In this post I will show another way to show information on the tile, badges. Badges are small icons that show up in the lower right corner of a tile on top of either the default startup tile, or on top of a notification. The process for displaying a badge is pretty much the same as displaying a notification, it just uses difference classes.

var xmlDocument = BadgeUpdateManager.GetTemplateContent(BadgeTemplateType.BadgeNumber);
xmlData.Text = xmlDocument.GetXml();
var textNode = xmlDocument.SelectSingleNode("/badge");
textNode.Attributes[0].NodeValue = UIBadgeValue.Text;
var badge = new BadgeNotification(xmlDocument);
BadgeUpdateManager.CreateBadgeUpdaterForApplication().Update(badge);


The first line gets the XML template for the badge. There are two template types for badges, Number and Glyph. Number display a one or two digit number. For example you could use this to display the number of unread e-mails in a e-mail application. The number badge looks like this:

NumberBadge

The second type is Glyph which displays one of a series of predefined icons. A error glyph badge looks like this:

GlyphBadge

The schema for both types of badges is the same:

<badge value=””/>  

The next two lines set the value attribute in the schema. For the number badge this will be one or two digits. For the glyph badge it will be one of the following values: none,activity,alert,available,away,busy,newMessage,paused,playing,unavailable,error The last two lines create a badge object and display it on the tile. Removing a badge works just like removing a notification:

BadgeUpdateManager.CreateBadgeUpdaterForApplication().Clear();

Just like notifications, badges have a ExpirationTime property that should control when the badge expires, but I have not had any luck getting that property to work.

Thursday, September 22, 2011

Metro App Tile Notification


In my last post I showed you how to configure the start menu tile for a Windows 8 Metro app. The tiles can be used for more the just displaying a static startup icon, they can also display content that is relevant to your app so that the user can get information from the app without even leaving the start menu.
There are a couple ways to do this. The first one I will show is notifications. A notification displays some content on the tile instead of its default text and icon. A good example of this is the Stocks app that comes with Windows 8. When you start the app the current stock information will be setup as notifications so when you go back to the start menu you will see the tile rotate through the values for each stock market. Let's take a look at how you do a notification in a C# Metro app.
Note: The current version of Windows 8 is pre-beta and still a little buggy. I have found this especially true with the notifications, sometime they just don't work for no apparent reason.

The appearance of a notification is controlled by an XML template, so the first step in sending a notification is to get a template to work with like this:

Note: You will want to include the Windows.UI.Notifications namespace.

var xmlTemplate = TileUpdateManager.GetTemplateContent(TileTemplateType.TileWideText01);

This command will return an XmlDocument object containing the TileWideText01 template that you can fill out with the data you want to display. You can see a full list of all the templates here. Unfortunately that page doesn't show the actual XML in the template which you need to know before you can modify it. You may want to put a TextArea on your application form and set it's Text property to xmlTemplate.GetXml() to see the XML. The XML for the TileWideText01 template looks like this:

<?xml version="1.0" encoding="utf-16"?> 

<tile>
  <visual lang="en-US">
    <binding template="TileWideText01">
      <text id="1"></text>
      <text id="2"></text>
      <text id="3"></text>
      <text id="4"></text>
      <text id="5"></text>
    </binding>
  </visual>
</tile> 

and the resulting 

tile will look something like this:

clip_image002

To get our text into the notification we need to modify the XML. Here I use XPath to select the first text node and set its value:

var textNode = xmlTemplate.SelectSingleNode("/tile/visual/binding/text[@id='1']"); 
var newText = xmlTemplate.CreateTextNode(text); 
textNode.AppendChild(newText); 

Next we need to create a tileNotification object from the xml:

var tileNotification = new TileNotification(xmlTemplate); 

Finally we need to update the notification on the tile:

var tileUpdater = TileUpdateManager.CreateTileUpdaterForApplication(); 
tileUpdater.Update(tileNotification); 

If you put this code in the form constructor of a C# Metro app, run the app, and then switch to the Start screen you will momentarily see the default startup tile, then the notification will slide into view. The notification will continue to be displayed even if the application is terminated, the computer restarted, or even if the app is un-installed and re-installed (I think this is un-intended and may change in later versions.)

There are two ways for you to remove the notification. The first way is to replace it with a different notification. The second way it to clear it with the following command:

TileUpdateManager.CreateTileUpdaterForApplication().Clear(); 

This will remove the notification and restore the tile to the initial startup appearance.

Normally you can only have one notification active at a time, but there is also a way to show multiple notifications. First execute this command:

TileUpdateManager.CreateTileUpdaterForApplication()

.EnableNotificationQueue(true); 

Then add up to five notifications and the tile will rotate between them. If you add more than five the most recent five added will be shown.

One other thing you can do with notifications is set an expiration date and time. You do that like this:

tileNotification.ExpirationTime = new DateTimeOffset(DateTime.Now.AddMinutes(5)); 

This command will make a notification expire 5 minutes after it has been added to the tile. After the notification expires the initial startup tile will be displayed just like when you use the Clear command.

Sunday, September 18, 2011

Metro App Tile Basics

In my last post I showed the basics of how to create a simple Metro app. By default the tile displayed on the start screen for the app is not very useful, so I'll show you how to change it.

First open the app you created last time, or create a new blank Metro app. When the project is open double click on Package.appxmanifest in the Solution Explorer, this will bring up an editor screen for the manifest. On the Application UI tab scroll down a little bit to the Tile section:

clip_image002

The first two properties define the image that will be used for the small and large tiles on the start screen. These images can either be .png or .jpg. The small logo must be 150x150 pixels, and the large must be 310x150 pixels. If you don't specify a large logo, then you will not be given the option to switch to a larger tile on the start screen.

The next property, Small Logo, is used to specify the logo that will appear for the application on the search results screen. This must be a 30x30 pixel .png or .jpg.

The Show Name property determines if the name of the application should be displayed on the tile. If you do not specify a Short Name the Display Name will be used. You can also control the color of the name text by using the Foreground Text drop down. Here is an example of a large logo with a solid blue background and the name shown:

clip_image003

The Background Color property is used to control the background color of the tile and the splash screen. You will only see the background color on a tile when you leave parts of the image transparent.

Friday, September 16, 2011

Windows 8 Metro Apps

One of the major new features in Windows 8 is the concept of Metro style apps. The term “Metro” is used to describe a new design style for application user interfaces and an apps overall user experience. The Metro style interface can currently be seen in the Microsoft Zune media player and the Windows Phone 7 operating system. For more information on Metro check out Microsoft’s Metro Design Language page.
Metro apps in Wind0ws 8 run under a totally new operating environment called Windows Runtime or WinRT. I am not going to get into the details of WinRT here since quite honestly I have still not entirely gotten my head wrapped around it. Fortunately WinRT supports various languages and technologies that you are probably already familiar with so it’s not to hard to  get up to speed writing Metro apps.
If you have installed the Windows 8 Developer Preview with developer tools you can use this walkthrough to make your first Metro app.

  1. Startup Visual Studio 11 Express
  2. Click New Project.
clip_image002
You will see templates for a Windows Metro style apps for each of the supported languages. Note that this preview version of Visual Studio is only setup to do Metro apps. Javascript apps use HTML and CSS for their user interface, but unlike browser based apps they can have full access to the WinRT runtime. VB.NET, C#, and Visual C++ all use XAML for their UI’s which should be familiar to anyone who has done WPF or Silverlight apps.
  1. Select the Windows Metro style template under Visual C#, and then click Application in the center panel. This will create a basic blank Metro app.
  2. For the Name of the application enter HelloWorld then click OK.
If we ran the app now we would just get a blank screen so let’s add a little bit of content.
  1. In the XAML view, between the Grid tags, add the following code:
<TextBlock Text="Hello World" HorizontalAlignment="Center" Margin="20" TextWrapping="Wrap" VerticalAlignment="Top" FontFamily="Georgia" FontSize="16"/>

  1. Save you program then click Run.
Once the program compiles and runs you will get a black screen with a clock icon as the app loads then a black screen with the words “Hello World” in the top center. The first thing you will notice is that the app takes up the entire screen, this is a major design elements of Metro apps. If you have a large enough screen Windows 8 will provide the ability to do two apps side by side, but the standard is going to be one app displaying at a time.


Another thing you will notice is that there is no obvious way to close the app. The app lifecycle is much different in Metro. When you switch from one app to another the current app goes into a suspended state but remains in memory, then if you switch back to it, it will become active again. If memory starts running low the OS will automatically start terminating suspended apps.


Press the Windows key to bring up the Metro Start screen, scroll all the way to the right and you will see this icon:


clip_image001


This is the default icon that represents you new app. If you hover your mouse over it the Hello World name will pop up. To get back to Visual Studio just click the Desktop tile on the Metro start screen. Since your app is still suspended in the background remember to click stop to terminate it.

Thursday, September 15, 2011

New Development Tools

In conjunction with Microsoft’s Build conference this week they have released preview versions of quite a few development tools.

Windows 8 – As I mentioned yesterday the developer previews of Windows 8 have been released.

ASP.NET MVC 4 Developer Preview 

Visual Studio 11 Developer Preview 

.NET Framework 4.5 Developer Preview

ASP.NET  4.5 Developer Preview

WCF Web API Preview 5

Windows Azure Toolkit for Windows 8

So many new technologies to learn, so little time!

Wednesday, September 14, 2011

Windows 8

Yesterday at Microsoft’s Build Conference they provided a lot of new information for developers about Windows 8. I highly recommend checking out the day one keynote speech, it’s long but worthwhile.

If you want to try out Windows 8 you can download a developer (pre-beta) preview here. There are 64 and 32 bit versions of just the OS, as well as a 64-bit version that also contains early versions of Visual Studio 11 and Expression Blend 5 that will allow you to immediately get started with Windows 8 development.

To try it out I decided to load the 64-bit version with the tools in a virtual machine. I first tried if with VMware Workstation, but it seemed to have a problem with the Win 8 installer and it failed before the install even got started. Virtual PC doesn’t support 64-bit, guests but I presume the 32-bit version of Windows 8 will work with it. I finally got it installed using Oracle Virtual Box, just remember that you need to have a processor that supports hardware virtualization to do this. The install went very smoothly with the exception of one crash while entering my Windows Live password. After a re-start the install process finished without any more problems.

The new Metro user interface can be a little tricky at first, especially if you don't have a computer with touch capability, so here are a few tips to help you out.

  1. Be sure you have you screen resolution set to at least 1024x768 or the Metro style apps will not start up.
  2. You can click on the Desktop tile to get to a Windows 7 style desktop. Once you have done that you can switch back and forth between the desktop and the Metro start screen using the Windows key.
  3. There is no Windows 7 style start menu; it's just the Metro start screen. There doesn't seem to be a way to turn the old start menu back on and no indication if Microsoft will add this feature or not.
  4. If you don't have touch, then you will need to fall back to keystrokes for a lot of things. Here are a couple useful ones:

Windows Key+F: Opens the search files panel

Windows Key+Q: Opens the search apps panel

Windows Key+C: Opens the charms panel

Windows Key+I: Opens settings charm

  1. To shut down Windows (you would think this would be obvious), press Windows Key+I, click the Power icon, then click Shut down or Restart from the popup menu.

Sunday, September 4, 2011

GridView Header Issue

 
If you have worked with the ASP.NET GridView you may notice an odd problem relating to the header text alignment. If you set the grid’s HeaderStyle.HorizontalAlign property to Left the headers will appear left aligned in Chrome, Firefox and older versions of IE (as well as IE compatibility mode), but in later version of IE the header text will stay centered instead of left aligned. Here is the HTML that comes from the GridView:

<table cellspacing="0" rules="all" border="1" id="GridView1" style="width:50%;border-collapse:collapse;">     
    <tr align="left">                
        <th scope="col">Field1</th>
        <th scope="col">Field2</th>
        <th scope="col">Field3</th>        
    </tr>         
    <tr>               
        <td>Data1</td>
        <td>Data2</td>
        <td>Data3</td>        
    </tr> 
</table>

The reason for this alignment problem is the align attribute on the <tr> element. In the later version of IE this alignment is not inherited by the <th> elements like it is in other browsers. I have been doing some reading on this issue and there seems to be some debate as to whether this is what the HTML specification intended or not. I will leave that debate to others and just show how to resolve the problem.
If you are not auto generating the columns you can fix this by setting the HeaderStyle.HorizontalAlign property to the appropriate value for each of your columns. So in this example I would set them to Left. The GridView will now output the following HTML:

<table cellspacing="0" rules="all" border="1" id="GridView1" style="width:50%;border-collapse:collapse;">
    <tr align="left">                
        <th align="left" scope="col">Field1</th>
        <th align="left" scope="col">Field2</th>
        <th align="left" scope="col">Field3</th>         
    </tr>
    <tr>
        <td>Data1</td>
        <td>Data2</td>
        <td>Data3</td>
    </tr>
</table>


You will see that each <th> element now has an align attribute which will work the same in any browser.


You also can achieve the same thing using CSS which has the advantage of working whether you are auto generating the columns or not. To do this first add this style to either the header of your page, or to a CSS file:


<style type="text/css"> 
    .gvclass table th {text-align:left;} 
</style> 

Then wrap your GridView in a div tag that uses the .gvclass:

<div class="gvclass"> 
    <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" Width="50%"> 
    </asp:GridView> 
</div>