| Comments

As someone who uses a few iOS devices around the house, I’ve become fond of visiting sites and seeing a little banner that lets me know that a native app is available for the web app I’m using.  This concept was introduced in iOS 6 and called “Smart App Banners” in the developer documentation.  You may have seen them as well

Smart App Banner example

I wanted to provide the same affordance for Windows Store apps and recalled there are already two ways to integrate the web app browsing experience with the native app in the Windows Store:

In iOS, this is implemented a bit natively in mobile Safari, not through any additional JavaScript files/functions.  As with any random idea I have, I always set out to search if it has been done before (often it already has).  I couldn’t find something like this specifically for Windows Store apps, however I did find an implementation for pre-iOS6 browsers as well as Android.  It was from Arnold Daniels and hosted on GitHub, so what’s a guy to do?  Fork it!

And that’s what I did: https://github.com/timheuer/jquery.smartbanner

With a few more conditional checks, if you put this in your web app/site now you’ll get it automatically linked to your Windows Store app if you have the correct meta tags.  For the implementation for Windows Store apps I’ve made some assumptions about the meta tags used.  The following would get you a good experience:

   1: <html>
   2:   <head>
   3:     <title>Hulu Plus</title>
   4:     <meta name="author" content="Hulu LLC"/>
   5:     <meta name="msApplication-ID" content="App" />
   6:     <meta name="msApplication-PackageFamilyName" content="HuluLLC.HuluPlus_fphbd361v8tya" />
   7:     <link rel="stylesheet" href="jquery.smartbanner.css" type="text/css" media="screen"/>
   8:     <meta name="msapplication-TileImage" content="http://wscont1.apps.microsoft.com/winstore/1x/c8ac8bab-d412-4981-8f31-2d163815afe4/Icon.6809.png" />
   9:   </head>
  10:   <body>
  11:         <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script>
   1:  
   2:         <script src="jquery.smartbanner.js">
   1: </script>
   2:         <script type="text/javascript">
   3:             $(function () { $.smartbanner() })
   4:         
</script>
  12:   </body>
  13: </html>

If you have the combination of linking your app using the msApplication-ID and msApplication-PackageFamilyName values and the pinned sites high fidelity msApplication-TileImage value to deliver the combined experience.  If you have all these, then the banner “just works” for you.

NOTE: Because the Microsoft documentation mixes msApplication and msapplication (note the casing on the “A”), you should use the capitalization (which is more consistent in the documentation) for ensuring it all works smoothly. 

Now some may use a different pinned site TileImage than that of what they may use for the app tile, however this can also be overridden in the options:

   1: $(function () { $.smartbanner({ icon:'http://some/url/to/tile/image.png' }) })

When done the web app/site would display a dismissable banner (using Hulu as an example here) on a machine running Windows 8:

Hulu smart app banner example

So adding one reference, 2 files and an initialization and you’ll help give your app a bit more promotional flare for those viewing in browsers other than the ‘modern’ IE view.  As you can see the screenshot above is from the desktop version which doesn’t take advantage of the other msApplication-** attribute usage in desktop mode.  The one thing it doesn’t do that the iOS system-level banner does is detect if the app is installed and change “view” to “open” however there isn’t a mechanism to easily detect if the app is installed using JavaScript from a web app.

NOTE: While the ‘View in Store’ button works in IE, Safari and Firefox it does not work in Chrome.  I’m not sure what any timeframe it would be for Chrome to support the store launch protocol.

Anyhow, I thought this might be a useful addition to app developers web apps that have a Windows Store app counterpart (and perhaps already have an iOS and Androi counterpart as well).  I’ve submitted a pull request to the project I forked from, but you can get it from my GitHub repository for jquery.smartbanner.

Hope this helps!

| Comments

In some of our internal discussion lists there was some questions about how to host certain content for their application.  Most of the discussion came up from apps needing a privacy policy (Rule 4.1 from the Windows Store App Certification Requirements).  Some folks had apps they just developed, but no “site” or service they were using.  But they needed to host a privacy policy.  Lots of thoughts were floated around and I suggested Azure Free Web Sites as an option.  I originally suggested it as a simple way you could just have a URL to a privacy policy, but…duh, you could easily use it as a very quick marketing site for your app.

Creating a web site in Windows Azure

If you didn’t know, Windows Azure allows you to create a free web site!  It is very quick and simple to set up once you have your Azure account set up.  After doing that go to the portal and choose to create a new Web Site.  I recommend picking from the gallery and choosing WordPress.  There is such a vast ecosystem around WordPress as a CMS system that it is simple to use and set up. 

NOTE: Of course you can use others, even a static web site using the TFS/Git deploy feature even.  Do whatever you want.  I just think WordPress is great and allows you to scale your site features without writing code, etc.

Choose to create a site from the gallery:

Azure Find Apps image

This will walk you through a wizard to pick some names and options.  It is pretty self explanatory.  Once completed you will see your site provisioned in the portal.

Azure web sites image

Just click that link and you will be taken to your site…which for WordPress will be the initial setup page to choose your login.

Choosing a WordPress Theme

Once in the WordPress admin site, choose the Appearance option on the left, then the Themes sub-menu.  Once there, go to the Install Themes tab to pick a theme from the gallery.  Optionally you can grab a premium theme from various sites.  There is one called “Responsive” (search for that term) that is in the built-in gallery, free, and actually serves the basic needs well.  We’ll choose that one:

Responsive theme install image

After you pick it you’ll want to Activate it as the current theme.  Now let’s do some simple configuration.

Configure the WordPress site

In order to serve the goal of making this more of a marketing site and to host our privacy policy we don’t need commenting on pages.  Additionally we want “nice” URLs for our site.  Let’s start with a few simple tweaks.

First (in the WordPress admin site) go to Settings->Permalinks.  Choose the “Post name” option.

WordPress permalink settings image

Next go to Settings->Discussions.  In the top uncheck the “Allow people to post comments on new articles” in the top:

WordPress discussion settings image

This will prevent commenting on content.  Next using the Responsive theme we can configure the home page.  Go to the Appearance->Theme Options section.  You’ll see a “Home Page” option for the Responsive theme.  You can set the main text, tagline and two other options.  This gives you the chance to set the URL for your app that is provided from the Windows Store. 

Here are some posts to help you find URLs for your app: Linking your apps on the web and Connect your web site to your store app.

Here is an example:

Responsive theme home page config image

Now go to Appearance->Widgets to modify some information on the home page for the 3 widget areas.  These could be simple things like a quick blurb about what the app is, maybe some top features, or whatever.  In the admin widget area you’ll see Home Page Widget 1,2,3.  Simply add the “Text” widget to these and you can add the title/text for this:

Home page widget image

You can also remove the theme logo to provide your own logo in the Appearance->Header section to provide your own image.  You can also specify a custom image on the main “hero” section of the home page instead of the default image and specify that.  Once all these quick tweaks are done, your home page is done.  Visit the site to see the quick changes.

Now let’s add our privacy policy so we have a permanent place for our privacy details.

Add a Privacy Policy page

From the WordPress admin site, go to Pages->Add Page.  Name it “Privacy Policy” and then type in your privacy policy text.  You can modify the text using HTML formatting to fit your needs.  Make sure to use the “Full Width Page” template so that it shows the entire page.  Notice the URL for the permalink.  I recommend keeping it simple with “privacy” or “privacy-policy” as the name (which should be default):

Privacy page editing image

Once you Publish the page, your site will now have a link to “Privacy Policy” on the home page and you can use that in your site, for your certification process and other areas you may need it.

You can now provide a link within your app to your privacy policy as well.  Andy has a simple method of adding it to the Settings charm and simply linking to your online site now.  You can visit the site to confirm it looks as you wish:

Privacy page image

Done!  You can see this example at http://timscoolapp.azurewebsites.net

Profit!

Now you have a free site on Azure to host marketing your app.  Of course this helps those getting over the hump with providing a nice place for a simple privacy page, but also enables you to have a way to provide other pages for your app.  You could provide more detail on features, have a form to collect feature requests, whatever.  WordPress is very flexible and the same process you used to create the privacy page can be used for other full-page content.  Or you can explore what WordPress has to offer you.  Again, there are many different ways you can do this and even within WordPress other themes you could choose.  However I think the Responsive one is a simple one to get started with as a base.

You may want to not have “azurewebsites.net” as your site URL as well.  If you wanted you can migrate to a shared instance (not free) and have custom domain name resolution on your Azure site as well.

Hope this helps!

| Comments

I’ve previously posted a few things about SQLite including a HOWTO on how to build from their source code.  If you still want to build your own DLL from their source code that is totally fine, but not necessary in most every single case I’ve seen in app usage.  One of the challenges I noted is that since SQLite is a native component and if you are a managed (.NET) app you can’t be architecture neutral anymore (AnyCPU).  What this means is that you have to build your app for each architecture you want to support: x86, x64 and ARM.  The flow of this using SQLite3.dll was that you would have to package, change the DLL, re-package. 

Not anymore.

In working with the great folks on the SQLite team, they’ve packaged the binaries up (for Windows 8 apps) in a nice installer using the Extension SDK format.  What this means is you now add a ‘reference’ to the SQLite binary and based on the architecture being built for your package, it will pull in the right DLL without you having to manage that yourself.  Here’s some step-by-step…

Installing the SQLite for Windows Runtime package

The first thing you want to do is install the package.  You can do this from within Visual Studio itself in all editions.  From the Tools menu, choose Extensions and Updates and then choose the Online section (on the left of the dialog) and search for ‘sqlite’ in the search term.  This will show you the SQLite for Windows Runtime package:

Visual Studio Extensions dialog

Click install my friends.  You will be prompted to restart Visual Studio which you should do.  Go ahead…I’ll wait.

Using the new package in your C#/VB app

Now that you have the SQLite for Windows Runtime package installed in your Visual Studio environment, you want to use it.  In a managed (.NET) app you would do the following steps.

First, create your app (e.g., a Blank XAML app is fine).  Once within your app, use the Add Reference mechanism to get to the next step.  Now you will not be browsing for any DLL directly like you would in a traditional .NET.  What we are adding here is a reference to the Extension SDK…not the library itself, a small but important distinction.  Once in the Add Reference dialog choose the Windows\Extensions view (see on left) and you’ll see SQLite for Windows Runtime.

To correctly use this in a managed app you’ll need to select that *and* the C++ runtime as seen below:

Add Reference dialog

The reason for this is to ensure that your app declares the right dependencies that are needed for the app to run.  The likelihood of the C++ runtime not being on a Windows machine where your app will be installed is extremely rare, but you need to declare this anyway.  Failure to do so will fail your app certification tests.

Now with this involved you can grab a managed wrapper to call the SQLite APIs as I’ve previously described in my HOWTO video.  I personally recommend the sqlite-net library (available via NuGet) to make this easier for you.

NOTE: sqlite-net is available as source in C#.  If you are using a VB app, you would first need to compile the sqlite-net source in a separate DLL so you can just add a reference to that in your VB project.

Using the sqlite-net library you can perform tasks using a model similar to LINQ2SQL where you can have types represent database entities:

   1: public sealed partial class MainPage : Page
   2: {
   3:     public MainPage()
   4:     {
   5:         this.InitializeComponent();
   6:         LoadData();
   7:     }
   8:  
   9:     public void LoadData()
  10:     {
  11:         var dbPath = Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "db.sqlite");
  12:         using (var db = new SQLite.SQLiteConnection(dbPath))
  13:         {
  14:             db.CreateTable<Person>();
  15:  
  16:             db.RunInTransaction(() =>
  17:                 {
  18:                     db.Insert(new Person() { FirstName = "Tim", LastName = "Heuer" });
  19:                 });
  20:         }
  21:     }
  22: }
  23:  
  24: public class Person
  25: {
  26:     [SQLite.AutoIncrement, SQLite.PrimaryKey]
  27:     public int ID { get; set; }
  28:     public string FirstName { get; set; }
  29:     public string LastName { get; set; }
  30: }

Now you just need to specify your architecture for your app (x86, x64, ARM) and when you build, the appropriate sqlite3.dll will be packaged in your app automatically.  This also happens during the packaging step for the store so the right item is included for each architecture-specific package.

WARNING: Do not package in DEBUG mode as you will fail certification.  Ensure that you build/package in RELEASE mode prior to submitting to the store or running the app certification toolkit (also referred to as WACK in some places).  You will get false positives if you are compiled in DEBUG mode.

This should make your development much easier without having to  swap out DLL files each time.

Using the new package in your C++ app

If you are a C++ developer you will do the same steps for installing and adding as a reference to your app.  In the C++ project system there is no 'Add Reference’ menu on the project context menu, but you will choose References and then the Add Reference button shows up.

Once you have the reference to the SQLite SDK then as a C++ developer you can just #include the header and go to work:

   1: #include <sqlite3.h>

Since C++ projects are already architecture-specific you don’t have to worry about the AnyCPU situation because there isn’t one!  You’ll get IntelliSense on the API by just including the header.  The Extension SDK mechanism already includes the C++ props file to help the project system know where to get the header for development and the lib for linking when building.  Most C++ developers will interact with SQLite using the native APIs and not need any additional wrapper library.

Using the new package in your JavaScript app

If you are using JavaScript/HTML to developer your app, you will follow the same flow as the C#/VB flow.  Add a reference to both the SQLite SDK as well as the C++ runtime (to declare the dependency).  As to accessing SQLite in your app, you’ll need a WinRT wrapper library to do that.  The one that seems to be gaining favor is the SQLite3-WinRT library on GitHub.  I have not personally used this, but seen a lot of people using this.  It allows you to use the JavaScript programming model in a familiar way:

   1: var dbPath = Windows.Storage.ApplicationData.current.localFolder.path + '\\db.sqlite';
   2: SQLite3JS.openAsync(dbPath)
   3:   .then(function (db) {
   4:     return db.runAsync('CREATE TABLE Item (name TEXT, price REAL, id INT PRIMARY KEY)');
   5:   })
   6:   .then(function (db) {
   7:     return db.runAsync('INSERT INTO Item (name, price, id) VALUES (?, ?, ?)', ['Mango', 4.6, 123]);
   8:   })
   9:   .then(function (db) {
  10:     return db.eachAsync('SELECT * FROM Item', function (row) {
  11:       console.log('Get a ' + row.name + ' for $' + row.price);
  12:     });
  13:   })
  14:   .then(function (db) {
  15:     db.close();
  16:   });

If using JavaScript this might be the way to go for your app.

Summary

I’m very glad the SQLite team worked to get this deployment package out there.  I think for some Microsoft developers, using SQLite is fairly new and this SDK package will make it easier to ensure you have the right bits at the right time.  Of course you are free to do it your own way, but I think this will ease the process a little bit.

Why no NuGet? Well, the NuGet infrastructure right now doesn’t support some of these semantics around native components to deal with headers, linking and architecture-specific deployments.  We’ll continue to work with them to see if we can drive these changes into that platform.

So please feel free to download via the Visual Studio ‘Extensions and Updates’ option from within VS, download directly from the Visual Studio Gallery, or download from the SQLite site themselves.  Once installed, once an update is available, VS will notify you that an update is available and you can install it.

Hope this helps!

| 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!