| Comments

At the “Developing Windows 8 Metro style apps with C++” event that happened on 18-May-2012, we saw and heard some very interesting things.  If you were watching live then hopefully you didn’t see how I tried to work through my presentation while my disk was suspiciously guzzling every last byte until it eventually ran out of space!  But I digress…

During the keynote presentation by Herb Sutter, we brought up several customers that are well-known in the native code world to talk about their experiences with Metro style apps and C++/Cx.  In particular hopefully this one caught your eye:

SQLite case study slide

That’s right, the team for SQLite was there to discuss how they were able to take their existing Win32 codebase and ensure that it worked well on Windows 8 as well as for Metro style apps.

SQLite is a in-process library that implements a self-contained, serverless, zero-configuration, transactional SQL database engine. The code for SQLite is in the public domain and is thus free for use for any purpose, commercial or private. SQLite is currently found in more applications than we can count, including several high-profile projects.

SQLite is an embedded SQL database engine. Unlike most other SQL databases, SQLite does not have a separate server process. SQLite reads and writes directly to ordinary disk files. A complete SQL database with multiple tables, indices, triggers, and views, is contained in a single disk file. The database file format is cross-platform - you can freely copy a database between 32-bit and 64-bit systems or between big-endian and little-endian architectures. These features make SQLite a popular choice as an Application File Format. Think of SQLite not as a replacement for Oracle but as a replacement for fopen().– Source: http://www.sqlite.org/about.html

Dr. Richard Hipp, the founder of SQLite, was on hand to announce the availability of the experimental branch they’ve been working on as well as that when the Release Preview of Windows 8 is made public that he will merge this code to the main trunk for SQLite, making it supported by them.  This is a really great thing for developers as SQLite has been a proven embedded database for numerous platforms and many, many customers.  The team prides themselves on testing and has millions of test cases that are validated each release.

As a Windows (and perhaps more specifically .NET) developer, you may not have had to build any lib from Open Source before of this type (i.e., native code) and since a binary is not being provided yet until Release Preview for Windows 8, I thought I’d share my tips on building the experimental bits, adding them to your projects and then using them with a client library.

UPDATE: I created a HOWTO video demonstrating the following steps of building and using from a C# Metro style app.

Building SQLite from source

If you are looking for the sqlite3.dll with this WinRT support anywhere on the sqlite.org site, you won’t find it.  You will have to build the source yourself. UPDATE:Since the origination of this post the SQLite team has released a version already compiled for 32/64-bit.  I highly recommend you get the code from the source rather than from any third party site.  Microsoft has worked with the team at SQLite to ensure compatibility and store certification.  For most .NET developers who have never grabbed native code source from an Open Source project and had to build it before, the maze of knowing what you should do can be confusing.  I’ve put together a cheat sheet on building SQLite from source for a Windows (and .NET developer) and put it on my SkyDrive: Building SQLite from source.  The OneNote I have has the details you need for the tools that will be required. 

In a nutshell you’ll need:

  • Visual Studio (easiest way to get the C++ compiler)
  • ActiveTcl
  • Update for gawk.exe
  • Fossil (the source control system used by SQLite)

Once you have these, you are ready to build SQLite.  Again, I’ll defer to my instructions on the details of setup.  Once your setup is complete, from a developer command prompt you’d run:

   1: nmake -f Makefile.msc sqlite3.dll FOR_WINRT=1

The result of this will give you basically 4 files that are of likely most importance to you: sqlite3.c, sqlite3.h, sqlite3.dll, sqlite3.pdb.

NOTE: The resulting pdb/dll that is built will be architecture specific.  If you used an x86 command prompt then that is what you have.  Be aware of this (as noted later in this post).

At a minimum you’ll want sqlite3.dll if you are a .NET developer, but as a native code developer you will likely be more interested in the others as well.  After this step, you now have a Windows Store compliant version of SQLite to include in your applications.

Runtime versus client access

Now at this point is where I’ve seen some confusion.  Folks are asking How do I include this, don’t I need a WinMD file to reference?  Let me diverge a bit and explain a few things.

The result of compiling the binary above produces primarily one thing…which I will call the “Engine” in this post.  This is the SQLite runtime and logic required to create/interact with SQLite database files.  This is NOT, however, an access library, which I will call the “Client” in this post.  If you are a managed code or JavaScript developer, at this point, all you have is the Engine, the database runtime.  You have no Client to access it.

Now, if you are a C++ developer you are probably okay at this point and don’t care much about what I have to say.  You have the header and are likely saying I’ve got the header, get out of my way.  And that is okay.  For C++ developers I think you’ll likely be accessing the database more directly through the SQLite APIs provided in the header.

I call out this distinction because this step provides you with the database engine you need to create a database and have it be store-compliant.  So if you are a JavaScript or .NET developer, what are you to do?  Stay tuned…let’s first get the Engine included in our app package.

Including SQLite in your app package

As I noted above, as a native code developer, having the header, lib and c file you may be okay and don’t care to read this.  I  personally think, however that I’d always just want the binary from my vendor rather than always include source in my files.  That said, the SQLite build process does product the amalgamation (sqlite3.c) you can just include in your native code app.

If you choose to go the binary file route (sqlite3.dll) then you need to simply follow a few principles to ensure that it is included in your package when you build your app/package.  These principles are simple:

  • include the architecture-specific binary
  • ensure the sqlite3.dll is marked as Content in your project
  • ensure you note that you now have a native code dependency (not needed if you are already a C++ Metro style app)

These two items will ensure that when you build (even for debug via F5) or when you package for the store, that the Engine is included in your package.  Marking as content is simply ensuring that after you add the file to your project, ensure the file properties note that it is content.  In .NET apps this is making the Build Action property Content.  In JavaScript applications ensure the Package Action is marked Content.

Declaring the native code dependency means you simply add a reference to the Microsoft C++ Runtime Library via the Add Reference mechanisms in .NET and JavaScript applications.  By doing this (and again, this is a requirement of including SQLite in your app) you now cannot be architecture-neutral. This means no more AnyCPU for .NET.  When producing a package you’ll have to produce architecture-specific packages before uploading to the store.  Not to worry though as Visual Studio makes this incredibly easy.  The one thing you’ll have to remember though is that you’ll have to change the sqlite3.dll before building the packages as the DLL is architecture-specific itself.

Now this all should be easier right?  Wouldn’t it be nice if you could just Add Reference to the Engine?  I personally think so.  I’ll be working with the SQLite team to see if they will adopt this method to make it as easy as this:

SQLite Extension SDK

In doing so, you as a developer would just add a reference to the Engine and then during build time Visual Studio (well MSBuild actually) will do all the right things in picking up the architecture-specific binary for your app.  No fiddling on your part.  This method also makes it easier for C++ developers as well as a props file would automatically be merged to include the .lib for linking and the header file for development.  This method uses the Visual Studio Extension SDK mechanism that was introduced in Visual Studio 11.

NOTE: Again note that as a managed (.NET) app I’d also have to ensure that my package includes the Microsoft C++ Runtime package in order for this to work and pass store certification.

Native code developers may scoff at this approach, but I could get started in 2 steps: Add Reference, #include.  No tweaking of my project files at all because the Extension SDK mechanism in VS does all this for me behind the scenes.

So why don’t I just give you the VSIX to install and accomplish the above?  Well simply, because SQLite is not my product and we’ve had a good relationship with their team and I want to make sure they understand the benefits of this method before jumping right in.  I hope that they will like it as I think it makes it *really* simple for developers.

Accessing the Engine from your app

Great, you’ve compiled the bits, you’ve understood how to ensure sqlite3.dll gets packaged in your application…now how do you use it!!!  Here’s the assessment of where we are at for Metro style apps as of the writing of this post.

C++ app developers: I think most C++ developers will get the header file (sqlite3.h) and be okay on their own with SQLite.  At this stage for them there doesn’t appear to be a real huge benefit of a WinRT wrapper to use the Engine.

.NET developers: I’ve messed around with a few libraries and believe the sqlite-net project to be the most favorable for what I believe most use cases will be for SQLite and Metro style apps.  This is a .NET-only library (not WinRT) but is basically a “LINQ to SQLite” approach.  The Mono team uses this one as well.  The necessary .NET 4.5 Core changes are already included in the project on github.  So you just need to get the SQLite.cs file and include it in your project.  Using this library allows you to write code like this:

   1: public sealed partial class BlankPage : Page
   2: {
   3:     public BlankPage()
   4:     {
   5:         this.InitializeComponent();
   6:  
   7:         string dbRootPath = Windows.Storage.ApplicationData.Current.LocalFolder.Path;
   8:         using (SQLiteConnection db = new SQLiteConnection(Path.Combine(dbRootPath, "mypeople.sqlite")))
   9:         {
  10:             db.CreateTable<Person>();
  11:  
  12:             db.RunInTransaction(() =>
  13:                 {
  14:                     for (int i = 0; i < 10; i++)
  15:                     {
  16:                         db.Insert(new Person() { FullName = "Person " + i.ToString() });
  17:                     }
  18:                 });
  19:         }
  20:     }
  21: }
  22:  
  23: public class Person
  24: {
  25:     [AutoIncrement, PrimaryKey]
  26:     public int ID { get; set; }
  27:     public string FullName { get; set; }
  28:     public string EmailAddress { get; set; }
  29:     public double Salary { get; set; }
  30: }

This is clearly just a sample, but demonstrates the simplicity of the library. 

NOTE: In the snippet above you do want to make sure you are creating your database in a path that is accessible from the AppContainer.  The best place is in the app’s ApplicationData location.  When specifying a path to SQLite in Open() for creation, give an explicit path always to ensure you aren’t relying on a temp file creation.

Some may ask about System.Data.Sqlite and this cannot be used because of the dependency of ADO.NET which is not a part of the .NET Framework Core profile.

Now this leads us to JavaScript developers.  Currently, there is not easy way for you to access this.  The Developer and Platform Evangelism team are working on some samples that are not quite complete yet.  JavaScript developers will need a WinRT library in order to access/create/query the Engine.  There are some out there (I haven’t played around with any of these) that would be good to see if they meet your needs.  Here are some pointers:

At the C++ event we talked with the SQLite team about a WinRT client library and will continue to talk with them to see if this is something of interest.  SQLite has a great history of working with the community and have a desire to continue this.  In the meantime, there are options for you to get started.  Also note, that since these are WinRT libraries they could also be used from C++ and .NET in Metro style apps.  At this point though it is my personal opinion that existing .NET libraries for .NET offer more value (i.e. LINQ) than how these WinRT ones exist.

Summary

This was a great announcement that the SQLite team made for Metro style app developers.  WinRT provides some existing local storage mechanisms which you should explore as well, however none that have structured storage with a query processor on top of it.  I’m really glad that the SQLite team was able to make a few diff’s to their code to accommodate a few store compliance areas and continue to offer their great product to this new class of applications.  It is very simple to get started by ensuring you have the Engine and picking your Client of your choice and write your app using SQLite for some local/structured storage!

Hope this helps and stay tuned for the release preview of Windows 8!

| Comments

Just a little post to point out a hidden gem if you are a .NET developer creating a Metro style app: you can bind to anonymous types.  This came up in a discussion with a customer today that I was having and, frankly, I never tried it until then because my mind was back in Silverlight where this isn’t possible.  There may not be a tone of cases where this is valuable for you, but knowing it is there may help.

Let’s assume I have a basic class Person:

   1: public class Person
   2: {
   3:     public int Age { get; set; }
   4:     public string FirstName { get; set; }
   5:     public string Gender { get; set; }
   6: }

And in my application I have a list of that Person type that I somehow received.  In this example, I’m just hard-coding it right now.

   1: List<Person> people = new List<Person>();
   2: people.Add(new Person() { Age = 38, FirstName = "Tim", Gender = "Male" });
   3: people.Add(new Person() { Age = 9, FirstName = "Zoe", Gender = "Female" });
   4: people.Add(new Person() { Age = 5, FirstName = "Zane", Gender = "Male" });

I can then decide I want to bind to a ListView control which has a particular template:

   1: <ListView x:Name="PeopleList" Width="500" Height="300">
   2:     <ListView.ItemTemplate>
   3:         <DataTemplate>
   4:             <StackPanel Orientation="Horizontal">
   5:                 <TextBlock Text="{Binding TheName}" Margin="0,0,10,0" />
   6:                 <TextBlock Text="{Binding GuysAge}" />
   7:             </StackPanel>
   8:         </DataTemplate>
   9:     </ListView.ItemTemplate>
  10: </ListView>

Notice that I’m binding to properties (TheName and GuysAge) that don’t exist on my Person class?  In my code, I can then create a LINQ query to filter out only the “dudes” from my list and bind that result:

   1: var onlyGuys = from g in people
   2:                where g.Gender == "Male"
   3:                orderby g.FirstName descending
   4:                select new
   5:                {
   6:                    GuysAge = g.Age,
   7:                    TheName = g.FirstName,
   8:                    Gender = "Dude"
   9:                };
  10:  
  11: PeopleList.ItemsSource = onlyGuys;

The result is that my ListView now shows 2 people in the list.  Nice.

Get in the real world

Now I would probably agree that since you already have a strongly-typed class this is probably not the use case here.  It certainly might be helpful, but you already have a class (and in this example, one that you completely control so you could shape it to be what you really need).  What about those times you don’t have a class or you don’t own the type coming back?  JSON ring a bell?  Using the sample JSON response (I’m not focusing on how to retrieve data here just how to bind to it) from Twitter APIs, we can demonstrate how this might be more helpful.  Here’s the Twitter JSON data I’m referring to in this example: Twitter Mentions API.

My app wants to retrieve and bind to Twitter data but I don’t really want to have a “TwitterResponse” data type that I have to serialize in/out in my code.  The mention data is an array of mentions.  For the sake of simplicity I’ve basically put my JSON string in a file rather than confuse this sample in how to work with Twitter.  My code looks like this (assume that ‘data’ is the resulting Twitter mentions JSON string:

   1: // parse the data into a JsonArray object
   2: var mentions = JsonArray.Parse(data);
   3:  
   4: // build the query out of the mentions
   5: var qry = from m in mentions
   6:           select new
   7:           {
   8:               MentionText = m.GetObject()["text"].GetString(),
   9:               FromUser = m.GetObject()["user"].GetObject()["screen_name"].GetString(),
  10:               ProfilePic = m.GetObject()["user"].GetObject()["profile_image_url"].GetString()
  11:           };
  12:  
  13: MentionData.ItemsSource = qry;

Notice the LINQ query for creating a “new” type that I will bind to my ListView.  In my XAML I have a simple DataTemplate to demonstrate:

   1: <ListView x:Name="MentionData" Width="500" Height="300">
   2:     <ListView.ItemTemplate>
   3:         <DataTemplate>
   4:             <StackPanel>
   5:                 <TextBlock Text="{Binding FromUser}" />
   6:                 <TextBlock Text="{Binding MentionText}" TextWrapping="Wrap" />
   7:             </StackPanel>
   8:         </DataTemplate>
   9:     </ListView.ItemTemplate>
  10: </ListView>

The result is me being able to create a LINQ query and create a new anonymous type and directly bind to it.

Voila!  Perhaps you already discovered this little gem and are using it.  It is a welcome addition to the data binding story for Metro style app development with XAML and .NET!  Of course the same benefit can be had for XML data using XLINQ queries, so while this example is for JSON data, really any source data applies…it is all about that new anonymous type you create!

Hope this helps!

| Comments

If you’ve been playing around with the Windows 8 Consumer Preview then hopefully you’ve seen the hundreds of samples provided and downloaded some apps form the store.  In a lot of those applications you’ll notice the common theme of the use of an AppBar…the command bar that shows when you swipe from the top or bottom of the screen.  You can also invoke the AppBar by right-clicking or using the Windows 8 keyboard shortcut of Windows key + ‘z’ to bring it up as well.

Bing Maps AppBar
Picture of the AppBar in the Bing Maps application

Most of the applications use the standard AppBar button concepts that clicking invokes some action for the app.  There may be times, however, where that button serves as a “toggle” to something in your app.  Using the Bing Maps app as an example, the “Show Traffic” command is actually a toggle command that, well, shows traffic.  You want to give your users some visual indication whether that toggle selection is on/off.  This can be accomplished in XAML by using 2 buttons and toggling their visibility, but that may be overkill for what you simple want to do.

The Visual Studio project templates provide a set of styles for the AppBar for you, but more importantly a base style AppBarButtonStyle that serves as the core design.  Altering this just slightly and you can have a ToggleAppBarButtonStyle for your project.  Here’s the style for that base:

   1: <Style x:Key="ToggleAppBarButtonStyle" TargetType="ToggleButton">
   2:     <Setter Property="Foreground" Value="{StaticResource AppBarItemForegroundBrush}"/>
   3:     <Setter Property="VerticalAlignment" Value="Stretch"/>
   4:     <Setter Property="FontFamily" Value="Segoe UI Symbol"/>
   5:     <Setter Property="FontWeight" Value="Normal"/>
   6:     <Setter Property="FontSize" Value="21.333"/>
   7:     <Setter Property="AutomationProperties.ItemType" Value="AppBar ToggleButton"/>
   8:     <Setter Property="Template">
   9:         <Setter.Value>
  10:             <ControlTemplate TargetType="ToggleButton">
  11:                 <Grid Width="100" Background="Transparent">
  12:                     <StackPanel VerticalAlignment="Top" Margin="0,14,0,13">
  13:                         <Grid Width="40" Height="40" Margin="0,0,0,5" HorizontalAlignment="Center">
  14:                             <TextBlock x:Name="BackgroundGlyph" Text="&#xE0A8;" FontFamily="Segoe UI Symbol" FontSize="53.333" Margin="-4,-19,0,0" Foreground="{StaticResource AppBarItemBackgroundBrush}"/>
  15:                             <TextBlock x:Name="BackgroundCheckedGlyph" Visibility="Collapsed" Text="&#xE0A8;" FontFamily="Segoe UI Symbol" FontSize="53.333" Margin="-4,-19,0,0" Foreground="{StaticResource AppBarItemForegroundBrush}"/>
  16:                             <TextBlock x:Name="OutlineGlyph" Text="&#xE0A7;" FontFamily="Segoe UI Symbol" FontSize="53.333" Margin="-4,-19,0,0"/>
  17:                             <ContentPresenter x:Name="Content" HorizontalAlignment="Center" Margin="-1,-1,0,0" VerticalAlignment="Center"/>
  18:                         </Grid>
  19:                         <TextBlock
  20:                         x:Name="TextLabel"
  21:                         Text="{TemplateBinding AutomationProperties.Name}"
  22:                         Margin="0,0,2,0"
  23:                         FontSize="12"
  24:                         TextAlignment="Center"
  25:                         Width="88"
  26:                         MaxHeight="32"
  27:                         TextTrimming="WordEllipsis"
  28:                         Style="{StaticResource BasicTextStyle}"/>
  29:                     </StackPanel>
  30:                     <Rectangle
  31:                         x:Name="FocusVisualWhite"
  32:                         IsHitTestVisible="False"
  33:                         Stroke="{StaticResource FocusVisualWhiteStrokeBrush}"
  34:                         StrokeEndLineCap="Square"
  35:                         StrokeDashArray="1,1"
  36:                         Opacity="0"
  37:                         StrokeDashOffset="1.5"/>
  38:                     <Rectangle
  39:                         x:Name="FocusVisualBlack"
  40:                         IsHitTestVisible="False"
  41:                         Stroke="{StaticResource FocusVisualBlackStrokeBrush}"
  42:                         StrokeEndLineCap="Square"
  43:                         StrokeDashArray="1,1"
  44:                         Opacity="0"
  45:                         StrokeDashOffset="0.5"/>
  46:  
  47:                     <VisualStateManager.VisualStateGroups>
  48:                         <VisualStateGroup x:Name="CommonStates">
  49:                             <VisualState x:Name="Normal"/>
  50:                             <VisualState x:Name="PointerOver">
  51:                                 <Storyboard>
  52:                                     <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGlyph" Storyboard.TargetProperty="Foreground">
  53:                                         <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemHoverBackgroundBrush}"/>
  54:                                     </ObjectAnimationUsingKeyFrames>
  55:                                 </Storyboard>
  56:                             </VisualState>
  57:                             <VisualState x:Name="Pressed">
  58:                                 <Storyboard>
  59:                                     <DoubleAnimation
  60:                                     Storyboard.TargetName="OutlineGlyph"
  61:                                     Storyboard.TargetProperty="Opacity"
  62:                                     To="0"
  63:                                     Duration="0"/>
  64:                                     <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGlyph" Storyboard.TargetProperty="Foreground">
  65:                                         <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemForegroundBrush}"/>
  66:                                     </ObjectAnimationUsingKeyFrames>
  67:                                     <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Content" Storyboard.TargetProperty="Foreground">
  68:                                         <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemPressedForegroundBrush}"/>
  69:                                     </ObjectAnimationUsingKeyFrames>
  70:                                 </Storyboard>
  71:                             </VisualState>
  72:                             <VisualState x:Name="Disabled">
  73:                                 <Storyboard>
  74:                                     <ObjectAnimationUsingKeyFrames Storyboard.TargetName="OutlineGlyph" Storyboard.TargetProperty="Foreground">
  75:                                         <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemDisabledForegroundBrush}"/>
  76:                                     </ObjectAnimationUsingKeyFrames>
  77:                                     <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Content" Storyboard.TargetProperty="Foreground">
  78:                                         <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemDisabledForegroundBrush}"/>
  79:                                     </ObjectAnimationUsingKeyFrames>
  80:                                     <ObjectAnimationUsingKeyFrames Storyboard.TargetName="TextLabel" Storyboard.TargetProperty="Foreground">
  81:                                         <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemDisabledForegroundBrush}"/>
  82:                                     </ObjectAnimationUsingKeyFrames>
  83:                                 </Storyboard>
  84:                             </VisualState>
  85:                         </VisualStateGroup>
  86:                         <VisualStateGroup x:Name="FocusStates">
  87:                             <VisualState x:Name="Focused">
  88:                                 <Storyboard>
  89:                                     <DoubleAnimation
  90:                                         Storyboard.TargetName="FocusVisualWhite"
  91:                                         Storyboard.TargetProperty="Opacity"
  92:                                         To="1"
  93:                                         Duration="0"/>
  94:                                     <DoubleAnimation
  95:                                         Storyboard.TargetName="FocusVisualBlack"
  96:                                         Storyboard.TargetProperty="Opacity"
  97:                                         To="1"
  98:                                         Duration="0"/>
  99:                                 </Storyboard>
 100:                             </VisualState>
 101:                             <VisualState x:Name="Unfocused" />
 102:                             <VisualState x:Name="PointerFocused" />
 103:                         </VisualStateGroup>
 104:                         <VisualStateGroup x:Name="CheckStates">
 105:                             <VisualState x:Name="Checked">
 106:                                 <Storyboard>
 107:                                     <DoubleAnimation
 108:                                     Storyboard.TargetName="OutlineGlyph"
 109:                                     Storyboard.TargetProperty="Opacity"
 110:                                     To="0"
 111:                                     Duration="0"/>
 112:                                     <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGlyph" Storyboard.TargetProperty="Foreground">
 113:                                         <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemForegroundBrush}"/>
 114:                                     </ObjectAnimationUsingKeyFrames>
 115:                                     <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundCheckedGlyph" Storyboard.TargetProperty="Visibility">
 116:                                         <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
 117:                                     </ObjectAnimationUsingKeyFrames>
 118:                                     <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Content" Storyboard.TargetProperty="Foreground">
 119:                                         <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemPressedForegroundBrush}"/>
 120:                                     </ObjectAnimationUsingKeyFrames>
 121:                                 </Storyboard>
 122:                             </VisualState>
 123:                             <VisualState x:Name="Unchecked"/>
 124:                             <VisualState x:Name="Indeterminate"/>
 125:                         </VisualStateGroup>
 126:                     </VisualStateManager.VisualStateGroups>
 127:                 </Grid>
 128:             </ControlTemplate>
 129:         </Setter.Value>
 130:     </Setter>
 131: </Style>

Now with that style we can have a simple style that shows a toggle on and off for the same button:

   1: ...
   2: <Page.BottomAppBar>
   3:     <AppBar>
   4:         <ToggleButton Style="{StaticResource ToggleAppBarButtonStyle}" 
   5:                 AutomationProperties.Name="Search" 
   6:                 Content="&#xE11A;" />
   7:     </AppBar>
   8: </Page.BottomAppBar>
   9: ...

The result would show:

 
ToggleButtonAppBarStyle in off/on state

This way we exhibit all the same behaviors of the AppBarButtonStyle, but just applied to the ToggleButton element in XAML.  Now we could probably refactor both to have an even more derivative base style and use more BasedOn styling, but how it is currently structured we couldn’t have a ToggleButton based on a Button style.  But thanks to the style/template engine in XAML we can re-use a lot and serve our needs!

Notice that you can set the Content to be whatever you want.  Since my base style uses the Segoe UI Symbol font, I’m setting the unicode value for a glyph here for Search.  A set of some cool glyphs you can use can be found in my previous post on XAML AppBar button styles.

You can get the ToggleAppBarButtonStyle from here: https://gist.github.com/2131230.

Hope this helps!

| Comments

Microsoft Advertising logoToday, the Microsoft Advertising team announced an update to their AdCenter SDK to include support for monetizing your Metro style apps.

In a blog post announcing the update, Ian notes that if you were using the previous SDK that there have been breaking changes and to use the updated SDK.  This update includes support for XAML applications and adding the ad units couldn’t be easier.  After installing their SDK (which was developed using the same distribution concepts in my post about creating a distributable custom control previous post), you will be able to use Add Reference in Visual Studio, navigate to the Windows/Extensions area and add the SDK.  After that it is as simple as adding the control in your project:

   1: <Grid Background="{StaticResource ApplicationPageBackgroundBrush}">
   2:     <Border Background="Red" VerticalAlignment="Bottom">
   3:         <ads:AdControl xmlns:ads="using:Microsoft.Advertising.WinRT.UI" 
   4:                        VerticalAlignment="Bottom" Width="728" Height="90" 
   5:                        AdUnitId="YOUR_AD_UNIT_ID" 
   6:                        ApplicationId="YOUR_APPLICATION_ID" />
   7:     </Border>
   8: </Grid>

Now you do, of course, have to have a pubCenter account and create the ad units beforehand in order for this to work, but that setup time didn’t take long at all.

You may have some time for your own ad units to be provisioned and start serving ads, but the ad team created some test values you can use to see how things all work.  Download the Ads SDK today!

Hope this helps!

| Comments

I hope that you had a chance to download the Windows 8 Consumer Preview.  One of the things that you will absolutely want to do is watch Jensen’s video as a video walk-through of Windows 8 features, focusing on working with the operating system as a user, introducing the gestures and things you want to know about.  It is a great, short video and you should definitely watch it:

As an avid keyboard user (and one without a touch device currently) I rely on the ‘desktop’ use of my Windows installation.  In addition to those things that Jensen mentions in his video, here’s a list of some helpful keyboard shortcuts…

ShortcutAction
Windows key + spacebarToggles between input languages and keyboard layout
Windows key + ,Peeks at the desktop
Windows key + EnterStarts Narrator
Windows Key + PgUpMoves full screen window (i.e., the new Metro UI) to the monitor on the left in multi-mon situations.
Windows Key + PgDnMoves full screen to the right
Windows Key + Shift + .
Windows Key + .
Snaps application and/or moves the snapped app to left/right
Windows Key + cOpens charms bar
Windows Key + iOpens Settings
Windows Key + kOpens Devices charm
Windows Key + hOpens Share charm
Windows Key + qOpens Search charm
Windows Key + wOpens Settings search
Windows Key + fOpens Files search
Windows Key + zToggle AppBar

These have been helpful for me to work through these new experiences quickly.  Hope this helps!