Scott Hanselman

It's 2012 and your kids have an iPhone - Do you know where they are? I do.

February 11, '12 Comments [30] Posted in Mobile | Musings
Sponsored By

Google Map Pin tells me your locationThe strangest thing just happened. I'm sitting here in a hotel in New Zealand and my phone pops up an alert from a push-to-talk voice chat application I recently installed called Voxer. It's a voicemail from a tween (a child perhaps not quite 13 - in-between) teasing me about my name. "Scott Hanselman - Who would name their kid Scott HanselAndGretal man. *giggle*" Harmless stuff, of course, but weird and random. No idea who this is.

The name wasn't familiar but there was a little icon next to the voicemail in the Voxer app. Perhaps you've seen it before. It was a little red pin.

I clicked, and the young person's exact location popped up. They were sitting in a public library, likely after school. Because the application is an iPhone app and tied into their identity, the app shows their full name, not an alias. Literally a light 20 seconds (not minutes, mind you) of Googling and I find their Google Plus profile and Twitter. Google Plus promotes even more "information leakage" with it's "Places Lived" feature. This showed the last three cities the young person lived in. One of them was Portland. Since I live in Portland that seemed too coincidental. I searched for people I know on Facebook with the same last name who lived in Portland. Turns out I'm Facebook-friends with this young person's dad, although both have long since moved out of town. I messaged him and he was appreciative, relieved it was me and not a stranger, and is dealing with his child.

What's the moral here friends? Let me break it down for you:

  • More apps leak your exact location than you realize.

    • These apps often ask you once, and then broadcast your location multiple times a day. I'm looking at you Facebook, Twitter, GroupMe, Voxer and Foursquare. I doubt anyone, including this young person, would ever guess that this little voice chat program would give up his address. If adults don't noticed this stuff, how is a teenager (or younger) supposed to?
    • Folks at Voxer - You need to make location services OFF by default.
  • Your kids have no idea. Yet.

    • They may be social this and savvy that, but honestly, they don't realize how much info they are leaking. Take a moment today and talk to them about it.

    • You've had the Drugs Talk, the Sex Talk, now have the Location Services Talk.

    • You can turn off Location Services on a per apps basis, and you can also turn on Restrictions on your phone so that only some apps (Find my Friends, for example) can access the GPS while others (Twitter, Voxer, etc) can't.

  • Have a Location Services policy for your family

    • As stupid as teens often are, they are smart when armed with information. Explain the situation, show them the control they have and apply your family policy.

Hope this helps your kids. Spread the word.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. I am a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web

The Web is the new Terminal: Are you using the Web's Keyboard Shortcuts and Hotkeys?

February 2, '12 Comments [45] Posted in HTML5
Sponsored By

My gmail looks like a terminal if you squint

A V100 Terminal - Creative Commons via blakespot on FlickrNUI is OUI, Dear Reader. About eight years ago I blogged about "text mode" and said (if I may be silly and quote myself):

"I’m just saying that my Tab,Tab,Tab,Enter will beat your Click,Tab,Alt-F,O,Click,Double-Click, more often than not." - Me

I like to look at the computer systems of the businesses that I visit on a regular but spaced apart basis over the course of years. You know these businesses - your dentist, your eye doctor, the car shop that changes your oil, perhaps your bank or finance person. You see them every 3 to 6 months, or perhaps over a many years.

At my automotive shop, I watch them move from:

  • Keyboard heavy, very fast
    • VT100 Dumb Terminal
    • Windows running a VT100 Dumb Terminal Emulator
    • Netscape with Java running a VT100 Dumb Terminal plugin
  • Mouse heavy, very slow
    • Ugly gray HTML application in Netscape
    • Pretty AJAXy HTML application in Firefox
  • Keyboard heavy, very fast
    • Very terminal-like AJAXY HTML application in Firefox
    • ???

Tab, Tab, Enter is just the start. I propose that the interaction model for this "timeline" looks like somewhat like this.

Bell curve showing Mouse and Keyboard on Y Axis and Time on X axis. Curve shows most sites use mice. We need more using keyboards.

If you are an airline counter customer service person, you're going to want to touch the mouse as little as possible. Every keystroke counts, in fact, and this is one of the reason that every airline counter system I've ever seen is either a terminal itself or a browser window into a terminal. The interaction model for an airline workers apps needs to be terse and crisp and keyboard based because they are using it all day.

When Web Sites start to become Web Applications that are used every day they have to have keyboard shortcuts. More and more if you app doesn't have them you're going to limit your audience.

All my favorite web applications use keyboard shortcuts, and you'll notice that they are coalescing around a few common patterns:

  • J, K to move up and down
  • Enter to select or expand
  • G + some letter to Navigate (Goto)
  • / for Search
  • ? for keyboard help

There are two kinds of hotkeys on the web, though. There are "accesskeys" which have been in HTML since forever, then there's "hotkeys" that are application specific and often done with JavaScript bindings or jQuery plugins like jquery.hotkeys. Implementing these takes virutally no effort and can pay off hugely with your most discerning customers. Logical hotkeys can also turn beginners into enthusiasts.

<gratuitous bold="true">There is literally no reason to not implement keyboard hot-keys in your web application other than you've likely forgotten it's important.</gratuitous>

Access Keys

Implementing accesskey requires only the will and some thought.

<label for="homePhone">Home phone:</label>
<input name="HomePhone" type="text" maxlength="20" id="homePhone" accesskey="H" title="Home phone" class="text-box" />

Here we've made "ALT-H" go to the Home text box. Do you want awesome and automatic "KeyTips" to appear when the user presses ALT? Use the lovely KeyTips jQuery plugin (on NuGet also). Visit the KeyTips jQuery demo page and hold down ALT to see the key tips.

KeyTips for accesskeys as a jQuery plugin

Access Keys are very easy to setup and now give your 8-hours-a-day data entry user a huge gift and keeps their hands off the mouse. Make sure you do some user experience testing - even if only with yourself - and do some standard tasks with your web application and count both keystrokes and mouse touches.

Hot Keys

Slightly more complicated is adding Hot Keys via JavaScript but only slightly. John Resig's jQuery.Hotkeys is a simple plugin that lets you add and remove keyboard handlers for events in any browser supported combination.

// e.g. replace '$' sign with 'EUR'
$('input.foo').bind('keyup', '$', function(){
this.value = this.value.replace('$', 'EUR');
});

You can bind with selectors so that keys are captured on specific inputs, like the replace/expand example above, or you can bind (and unbind to the document with optional modifiers:

$(document).bind('keydown', 'ctrl+g', myfunc);

Sushant Bhatia has a great blog post (coincidentally written within minutes of mine, great minds think alike!) that talks about the importance of keyboard UX and how hotkeys are always preferable over tab, tab, tab.

Example Web Applications with Awesome Keyboard support

Here's some of the best examples I (and you, thanks Dear Reader for helping!) could find of great Keyboard support in Web Applications.

Twitter

I use these Twitter keyboard shortcuts all the time. You don't need to learn them all. Just use . for refresh, / for search and G-R for replies and you're already ahead of the pack.

Gmail

Gmail really gets credit for proving, in my opinion, that hotkeys on the web can be done elegantly and "just work." It may take a day or two but once you learn how to triage your email with just your keyboard you'll be surprised how fast you can get in and out and back to work.

I use J and K to navigate, X to select then # to delete or E to archive. Bam, bam, bam.

Gmail Hotkeys

Hotmail

Hotmail? Yes, while Hotmail drops the box by not including a help popup for the ? button, Hotmail not only supports their own keyboard shortcuts, but also familiar shortcuts from Gmail and Yahoo.

Windows Live Hotmail Hotkeys and Keyboard shortcuts

GitHub

Another example of a site you may be on for hours if it's part of your work. Github also supports ? for help and gives lots of shortcuts. Theirs are also J and K (which have meant up and down for folks familiar with vi and *nix editors) for moving up and down as well as X for toggling selection like Gmail, C for great, and / for search. You see how a pattern is developing on its own?

Some GitHub keyboard shortcuts

There doesn't appear to be a Help page with the list of Github keyboard shortcuts so for now, go over there, login and press ? to explore the complete list.

Jira Bug Tracker

Jira from Atlassian is a popular bug tracker with this same keyboard model. Every web application needs to include a web popup like this when ? is pressed.

Some Jira shortcuts

Remember The Milk

Remember The Milk is a web-based todo application with lots of mobile versions as well. However, they are best known by their web application which was very innovative when it first came out.

In fact, they were the first web application I ever used that actively marketed their application as being keyboard friendly. I love that we're at a time in the web where that is possible.

Remember The Milk has an extensive list of keyboad shortcuts

Asana

Asana is a team-focused shared todo list for projects and project management. They are super-focused on keyboard support and use it in all their promotional video AND think it is so important that they keep on the screen all the time! Classy.

Asana's Keyboard shortcuts are front and center

And they have LOTS, very logical and organized.

image

Trello

Trello's up and coming project management board software also leans heavily on hotkeys.

image

YouTrack

YouTrack from JetBrains says this about itself: "YouTrack is a keyboard-centric application and provides enough keyboard support to let you forget about using the mouse in most cases." Sassy!

Personally, I'm moving away from the Ctrl-Alt-This and That and prefer simpler hotkeys like these for YouTrack.

A subset of YouTrack Hotkeys

And as this isn't an exhaustive list but rather a long list to make a point, how about DuckDuckGo.

DuckDuckGo

The little search engine that could, DuckDuckGo includes keyboard shortcuts not just to move around search results but also another unusual keyboard-centric feature they called !Bang.

I keep DuckDuckGo.com as my home page. If I want to search them, I search. If I want to search Bing I type "hanselman b!" or Google with "hanselman g!" or hundreds of other sites like "hanselman image!" or even super specific site searches like "hanselman csharp!"

Now THAT'S keyboard friendly.

image

Conclusion

Like it or not, there's a standard brewing on the web. Not only should you have accesskey support (should have done this years ago) but also extensive keyboard shortcuts if you expect your users to spend serious time with your application.

At the very least, I think it's fair to say that these are de facto standard shortcuts now on the web and you should think about what that means for your application:

  • J, K to move up and down
  • Enter to select or expand
  • G + some letter to Navigate (Goto)
  • / for Search
  • ? for keyboard help

Good shortcuts mean happy and engaged users.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. I am a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web

Prompts and Directories - Even Better Git (and Mercurial) with PowerShell

February 1, '12 Comments [36] Posted in Open Source | PowerShell
Sponsored By

posh-git with custom directoryI love PowerShell and spent years and years working with it since it first came out. I've actually got 15 or so pages of PowerShell posts on this blog going way back.

PowerShell is insanely powerful. I would even go so far as to say it was (is) ahead of its time. PowerShell is totally dynamic and is almost like having JavaScript at the command line, but even more thoughtfully designed. I appreciate folks that love their bash shells and what not, but PowerShell can do some wonderful things.

A long time ago (2009) Mark Embling blogged about a nice prompt with TabExpansion that he'd made to make working with PowerShell and Git (his favorite source control system) nicer. Later, Jeremy Skinner added TabExpansion for common commands. A little while later Keith Dahlby started with their code (with their blessing) and posh-git was born. Expanding even more, Jeremy later created posh-hg (for Mercurial, my favorite source control system).

All of these are currently in use in various forms. Just recently (days ago, even) while I was trying figure out how to get these two separate but similar PowerShell scripts to live together when Keith created a small shared function that makes sharing prompts easier.

I think that Git Bash on Windows needs to go away. It's just not useful to say that a Windows user has to run Bash in order to use Git. PowerShell with Git (or your favorite VCS) is demonstrably better for Windows folks. I also feel that the installation for posh-git, while it uses PsGet (think NuGet for PowerShell, which is INSANELY awesome), just could be easier.

I happened to be tweeting about this and ended up doing a Skype+Join.me 3-way pair programming session with Keith and Paul Betts to explore some ideas on the topic. While a customized prompt is cool, I wouldn't rest until we'd modified "dir/ls" to show source control status. I'm not talking about a PowerShell Provider, I'm talking about extending the View for the result of a dir (get-childitem and a FileInfo) itself.

I want to be able to take a fresh machine and fresh PowerShell installation, invoke one PsGet command and get Git and Hg (and whoever else) integration with PowerShell, a new prompt AND new (yet to be written at this point) directory listing support.

We did some pairing as I sat in a pub and drove while Keith and Paul told me I was a lousy typist. We got a nice prototype working and I went home. After the kids went to sleep I was asking questions on a mailing list and ended up getting an answer from James Brundage, noted PowerShell expert. I'd met James at a Nerd Dinner in Seattle once and gave him a book. He was kind enough to do a screen sharing session with me and refactor my directory spike (and some of posh-git) into a more useful form. It's still a spike, but Keith and I are going to merge all three of them (posh-git, posh-hg and my VCS dir stuff) into one usable and easy to install module. I'm sure we'll both blog about it when it's cleaner. I'm hoping we'll get it all integrated into a single install line:

(new-object Net.WebClient).DownloadString("http://psget.net/GetPsGet.ps1") | iex
install-module posh-git

Here's the general idea that encapsulates a number of these ideas. Rather than scripts that are plugged into your PowerShell $profile, we'll have a module or two like this.

C:\Users\Scott\Documents\WindowsPowerShell\Modules
$ dir

Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 1/31/2012 10:37 PM Posh-Git
d---- 1/31/2012 10:37 PM Posh-GitDir
d---- 1/31/2012 12:27 AM PsGet

The Posh-Git folder is the Posh-Git source as it is, as a module and imported in your profile like this.

Import-Module Posh-Git
Import-Module Posh-GitDir

Posh-GitDir is my extension module that will change dir/ls/get-childitem and add a Git Status column. I've added extra columns with file information before in PowerShell, except in a cheesy way and I never actually overrode dir directly.

First, we'll make a post-gitdir.Types.ps1xml that adds the new ScriptProperty that pulls details for each file out of a $GitStatus variable that's added each time the prompt is drawn.

<?xml version="1.0" encoding="utf-8" ?>
<Types>
<Type>
<Name>System.IO.FileInfo</Name>
<Members>
<ScriptProperty>
<Name>Git</Name>
<GetScriptBlock>
$retVal = ""
if ($GitStatus.Index.Added -contains $this.Name) { $retVal += "+" } `
elseif ($GitStatus.Index.Modified -contains $this.Name) { $retVal += "~" } `
elseif ($GitStatus.Index.Unmerged -contains $this.Name) { $retVal += "!" } `
else { $retVal += " " }

$retVal += " "

if ($GitStatus.Working.Added -contains $this.Name) { $retVal += "+" } `
elseif ($GitStatus.Working.Modified -contains $this.Name) { $retVal += "~" } `
elseif ($GitStatus.Working.Unmerged -contains $this.Name) { $retVal += "!" } `
else { $retVal += " " }

$retVal
</GetScriptBlock>
</ScriptProperty>
</Members>
</Type>
<Type>
<Name>System.IO.DirectoryInfo</Name>
<Members>
<ScriptProperty>
<Name>Git</Name>
<GetScriptBlock>
""
</GetScriptBlock>
</ScriptProperty>
</Members>
</Type>
</Types>

This adds the Git column to the output as a ScriptProperty, but doesn't change the default view.

$ dir | get-member

TypeName: Get-ChildItem

Name MemberType Definition
---- ---------- ----------
Mode CodeProperty System.String Mode{get=Mode;}
Create Method System.Void Create(System.Security.AccessControl.DirectorySecurity director...
CreateObjRef Method System.Runtime.Remoting.ObjRef CreateObjRef(type requestedType)
...snip...
BaseName ScriptProperty System.Object BaseName {get=$this.Name;}
Git ScriptProperty System.Object Git {get="";}

I'd have to always select manually, which is tedious.

$ dir | select Name, Git

Name Git
---- ---
CommandType.cs ~
Connection.cs ~
ConnectionExtensions.cs ~
ConnectionManager.cs +
ConnectionScope.cs +
GuidConnectionIdFactory.cs ~

We want to change the dir "view" itself.  We have to copy the default view for a directory at: "C:\Windows\system32\WindowsPowerShell\v1.0\FileSystem.format.ps1xml" and add our new column.

<?xml version="1.0" encoding="utf-16"?>
<Configuration>
<ViewDefinitions>
<View>
<Name>Dir-Git</Name>
<ViewSelectedBy>
<TypeName>Dir-Git</TypeName>
</ViewSelectedBy>
<TableControl>
<TableHeaders>
<TableColumnHeader>
<Label>Git</Label>
<Width>4</Width>
<Alignment>left</Alignment>
</TableColumnHeader>
...snip...
</TableHeaders>
<TableRowEntries>
<TableRowEntry>
<Wrap/>
<TableColumnItems>
<TableColumnItem>
<PropertyName>Git</PropertyName>
</TableColumnItem>
...snip...
</TableColumnItems>
</TableRowEntry>
</TableRowEntries>
</TableControl>
</View>
</ViewDefinitions>
</Configuration>

For the design, I want the Indexed and Working files in two columns, showing Added+, Modified~ and Unmerged! files like this. Deleted files won't show up cause they aren't there.

$ dir #snipped out directories and files for clarity

Mode Git LastWriteTime Length Name
---- --- ------------- ------ ----
d---- 1/31/2012 5:14 PM Configuration
d---- 1/31/2012 5:14 PM Hosting
-a--- + 1/31/2012 5:14 PM 2170 ConnectionManager.cs
-a--- + 1/31/2012 5:14 PM 402 ConnectionScope.cs
-a--- ~ 1/31/2012 5:14 PM 280 GuidConnectionIdFactory.cs
-a--- 1/31/2012 5:14 PM 273 IConnection.cs
-a--- ~ 1/31/2012 5:14 PM 165 IConnectionIdFactory.cs
-a--- + 1/31/2012 5:14 PM 304 IConnectionManager.cs
-a--- 1/31/2012 5:14 PM 118 packages.config
-a--- ~ 1/31/2012 5:14 PM 8296 PersistentConnection.cs
-a--- + 1/31/2012 5:14 PM 1118 PersistentConnectionFactory.cs
-a--- 1/31/2012 5:14 PM 623 PersistentResponse.cs
-a--- ~ 1/31/2012 5:14 PM 1288 SignalCommand.cs
-a--- ~ 1/31/2012 5:14 PM 7386 SignalR.csproj
-a--- 1/31/2012 5:14 PM 23076 TaskAsyncHelper.cs
C:\Users\Scott\Desktop\github\SignalR\SignalR [master +1 ~0 -0 | +10 ~58 -11 !]

We import these modules in our $profile.

Import-Module Posh-Git
Import-Module Posh-GitDir

The posh-git module adds the custom prompt (if you haven't changed yours) with a new function called Write-VcsStatus that is shared between Hg and Git (and any other systems that want to play with us). It only adds the prompt if the user hasn't already customized their prompt. If they have, they'll need to incorporate Write-VcsStatus themselves.

$defaultPromptHash = "HEYStcKFSSj9jrfqnb9f+A=="

$md5 = [Security.Cryptography.MD5]::Create()
$thePrompt = [Text.Encoding]::Unicode.GetBytes((Get-Command prompt | Select-Object -ExpandProperty Definition))
$thePromptHash = [Convert]::ToBase64String($md5.ComputeHash($thePrompt))

if ($thePromptHash -eq $defaultPromptHash) #using the default prompt?
{
#recommend our own
function prompt(){
# Reset color, which can be messed up by Enable-GitColors
$Host.UI.RawUI.ForegroundColor = $GitPromptSettings.DefaultForegroundColor

Write-Host($pwd) -nonewline -foregroundcolor white

Write-VcsStatus

Write-Host ""
return "$ "
}
}
else {
Write-Debug "Make sure your prompt includes a called to Write-VcsStatus!"
}

The craziness that James Brundage came up with to override dir/ls/get-childitem was this. He said he'll do a complete tutorial on his blog with technical details for the generic case.

. ([ScriptBlock]::Create("
function Get-ChildItem {
$([Management.Automation.ProxyCommand]::GetCmdletBindingAttribute((Get-Command Get-ChildItem -CommandType Cmdlet)))
param(
$([Management.Automation.ProxyCommand]::GetParamBlock((Get-Command Get-ChildItem -CommandType Cmdlet)))
)

process {
Microsoft.PowerShell.Management\Get-ChildItem @psBoundParameters |
ForEach-Object {
`$null = `$_.pstypenames.Insert(0, 'Dir-Git')
`$_
}
}
}
"))

Tie it all up with a .psd1 file that has the list of Scripts, Types, Formats and the Module.

@{
ModuleVersion="1.0.0.0"
Author="Scott Hanselman"
Description="Posh-GitDir"
CompanyName="Hanselman and Friends"
RequiredModules="Posh-Git"
ScriptsToProcess="prompt.ps1"
TypesToProcess="posh-gitdir.Types.ps1xml"
FormatsToProcess="posh-gitdir.Format.ps1xml"
ModuleToProcess="posh-gitdir.psm1"
}

To recap, this new module requires the posh-git module, it ands our new "Dir-Git" type, adds the Git ScriptProperty in Types, and shows how to Format it, and overrides get-childitem in the psm1. If you didn't want to override dir proper, maybe you could make a dir-git or dir-hg.

Next steps are for us to integrate them into one module, bring in an inproc library to access the source info (rather than regex'ing the output of git status and hg status) which would speed it up 10x I'm sure, as well as better NuGet support.

In this screenshot you can see posh-git and posh-hg living together. The first directory is a hg repo with a 1 file not in control. The second directory is a git repo with 1 file added in the Index, 10 new added in working, 58 modified, and 11 deleted.

PowerShell with Git and Hg

Keith and Jeremy have done some amazing work. Open Source, baby. I'm looking forward to pairing with them in coming days and buttoning this up. I've been a hardcore Tortoise (Tortoise-Hg, Tortoise-SVN, Tortoise-Git) source control user, but the addition of PowerShell is shaking my faith in a good way. At leat to the point that I think it's worth my spare time to see this through.

Thoughts?

Related Links

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. I am a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web

One ASP.NET Sneak Peek: Elegant Web Forms and Snowballs in Hell

February 1, '12 Comments [72] Posted in ASP.NET
Sponsored By

For the most part, I'm an ASP.NET developer. I don't need to specify MVC or Web Forms, because it's all One ASP.NET its core. My apps are often hybrids and include not just Web Forms or MVC but also SignalR and Web API.

Web Forms often gets picked on because of large View State, weird markup or maybe folks don't like the controls model. However, Web Forms has its place and it's getting even better with .NET 4.5. Here's a little sneak peek of some cool ideas Damian Edwards and the team have been working on for the next version of ASP.NET.

As a place to start, remember that ASP.NET routing started in MVC and moved into core ASP.NET. Routing is useful in all ASP.NET applications - MVC, Web Pages and Web Forms. Model Binding is coming to Web Forms as well, as well as Strongly Typed Data Controls and some other features that make both the code and the result pretty compelling. Dare I say, elegant. Elegant Web Forms? Madness! Who is this fool?

Here's a sortable grid with Create, Edit, Delete in Web Forms 4.5. An experiment for you, Dear Reader, would be to do the same thing I'm doing here in ASP.NET MVC or Web Pages.

Do note that this is fresh off Damian's laptop, and it's a experiment.

First, note the clean URLs. Use Routing, Web Forms people. You have no reason not to.

Clean URLs in WebForms. Scandalous.

Here's what it'll look like:

Databinding in ASP.NET Web Forms 4.5 Sneak Peek

Right now in this experiment, there is this routing table. Personally I'd like a convention for CRUD to make this one line.

Routes.MapPageRoute("CategoriesNew", "Categories/New", "~/Categories_New.aspx");
Routes.MapPageRoute("CategoriesEdit", "Categories/{id}", "~/Categories_Edit.aspx");
Routes.MapPageRoute("CategoriesDelete", "Categories/{id}/Delete", "~/Categories_Delete.aspx");
Routes.MapPageRoute("Categories", "Categories", "~/Categories.aspx");

Here's the  Grid. Now, before you declare that's too freaky, take a look and note there's a lot of functionality going on here in not too many lines. ItemType (was ModelType in the Developer Preview) is strongly typing this grid to the Category model. Notice SelectMethod. You just need to provide a method here that returns an iQueryable, in this case, GetCategories.

UPDATE with NOTE: See the comments below. Damian Edwards says: "That said, you don't need to return IQueryable. You can happily return an IEnumerable and just take in the extra parameters that the GridView will give you to ensure you can retrieve only the data for the currently requested page and sorted by the chosen column."

<asp:GridView runat="server" ID="categoriesGrid" CellSpacing="-1" GridLines="None"
ItemType="VS11Experiment.Model.Category" DataKeyNames="CategoryId"
AutoGenerateColumns="false"
AllowPaging="true" AllowSorting="true" PageSize="5"
SelectMethod="GetCategories">
<Columns>
<asp:DynamicField DataField="Name" />
<asp:DynamicField DataField="Description" />
<asp:TemplateField>
<ItemTemplate>
<a runat="server" href='<%# GetRouteUrl("CategoriesEdit", new { id = Item.CategoryId }) %>'>edit</a>
<a runat="server" href='<%# GetRouteUrl("CategoriesDelete", new { id = Item.CategoryId }) %>'>delete</a>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<EmptyDataTemplate>
No categories found.
</EmptyDataTemplate>
<SortedAscendingHeaderStyle CssClass="asc" />
<SortedDescendingHeaderStyle CssClass="desc" />
<PagerStyle CssClass="pager" />
</asp:GridView>

"OK, Hanselman, what hellish code-behind are you going to show us now? What Satan's spawn have you been shining us on with all this time only to spring the nasty stuff at the last minute? I know you crafty Microsoft types, always creeping around with your Legos and your Windows Phones."

Fine, you caught me.

public partial class Categories : System.Web.UI.Page
{
private readonly DemoWhateverDataContext _db = new DemoWhateverDataContext();

public void Page_Load()
{
if (!IsPostBack)
{
// Set default sort expression
categoriesGrid.Sort("Name", SortDirection.Ascending);
}
}

public IQueryable<Category> GetCategories()
{
return _db.Categories;
}
}

Aargh! My eyes! Wait, that doesn't suck at all. Even better if I could hypothetically put the default sort on the GridView and lose the whole Page_Load.

Whatever database or repository or Web (HTTP) Service you like, as long as your data access layer returns some IQueryables and you're in a good place. Sorting happens via LINQ so your data access layer can do the work, not ASP.NET.

So listing categories in a grid is decent, what's Edit look like?

Editing with ASP.NET Web Forms 4.5

If you add Model Binding to ASP.NET WebForms you spend less time digging around in the Request object. Notice that we're not doing that all here.

See how the RouteData attribute on GetCategory pulls the id out of the URL Categories/1?

public partial class Categories_Edit : System.Web.UI.Page
{
private readonly DemoWhateverDataContext _db = new DemoWhateverDataContext();

public Category GetCategory([RouteData]int? id)
{
return _db.Categories.Find(id);
}

public int UpdateCategory(int categoryId /* Comes from the data control itself via DataKeyNames property */)
{
var category = _db.Categories.Find(categoryId);
TryUpdateModel(category);
if (ModelState.IsValid)
{
return _db.SaveChanges();
}
return 0;
}

protected void categoriesForm_ItemUpdated(object sender, FormViewUpdatedEventArgs e)
{
Response.RedirectToRoute("Categories");
}

protected void categoriesForm_ItemCommand(object sender, FormViewCommandEventArgs e)
{
if (e.IsCancel())
{
Response.RedirectToRoute("Categories");
}
}
}

Often folks point to ASP.NET MVC's ability to use PRG (Post Redirect Get) as a strength. Often PostBacks in WebForms are looked down upon. In this model above, we're also totally able to use the PRG interaction model in Web Forms. See how the item is updated and we redirect to a route.

And the categoryId on UpdateCategory() comes from the Form View that is HTTP posting the data back. Here's a snippet:

<asp:FormView runat="server" ID="categoriesForm" RenderOuterTable="false"
ItemType="VS11Experiment.Model.Category" DataKeyNames="CategoryId"
DefaultMode="Edit"
SelectMethod="GetCategory" UpdateMethod="UpdateCategory"
OnItemUpdated="categoriesForm_ItemUpdated"
OnItemCommand="categoriesForm_ItemCommand">

Also, you know how in ASP.NET MVC you've got unobtrusive JavaScript validation that is driven by the model class itself?

Edit Category in ASP.NET Web Forms

In ASP.NET MVC one often uses EditorFor, and in Web Forms we've got Dynamic Control. The idea being that Dates get Calendars and you can replace the UI completely using a field template. That feature actually started in Web Forms Dynamic Data and then moved to ASP.NET MVC. Features move both ways when it's all ASP.NET underneath. See what I did there?

<EditItemTemplate>
<ol>
<li><label>Name:</label>
<asp:DynamicControl runat="server" ID="name" DataField="Name" Mode="Edit" />
</li>
<li><label>Description:</label>
<asp:DynamicControl runat="server" ID="description" DataField="Description" Mode="Edit" />
</li>
</ol>
...

And when these forms are POSTed, you'll need validation. Rather than Validation Controls, in this case since we already know about the model we can use unobtrusive validation, similar to ASP.NET MVC. The idea is push the best ideas into the core of ASP.NET and make common stuff easy while letting people work the way they want to work.

public class Category
{
[ScaffoldColumn(false), Display(Name="Id")]
public long CategoryId { get; set; }

[Required, StringLength(100)]
public string Name { get; set; }

[StringLength(10000), DataType(DataType.MultilineText)]
public string Description { get; set; }
}

Sure, ASP.NET Web Forms may not be your cup of tea just like ASP.NET MVC might not be either. But remember that it's all One ASP.NET, and you've got a number of tools in your toolkit. Pick the ones that make you happy.

One ASP.NET Diagram

*And no, Hell isn't a dirty word in this context. ;)

Related Links

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. I am a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web

From Concept to Code in 6 hours: Shipping my first Windows Phone App

January 30, '12 Comments [49] Posted in Open Source | WinPhone
Sponsored By

A screenshot of my new app Lost Phone Screen for Windows Phone 7Warning, this is long. I'll be frank with you, as I always am. I have an iPhone, a number of iPads and I like them fine. I have a Windows Phone that I use occasionally. I know C# but I do not know Objective-C.

TL;DR Version

I made my first Phone Application. I've spent about 6 hours on it. It's called Lost Phone Screen and it makes nice wallpaper. It's over at http://lostphonescreen.com. It's a simple customizable Windows Phone 7 Lockscreen. It was way easier and more fun to make than I expected. If I make a million bucks with this thing I'm GONE. You'll never see me again. :)

Introduction

I wanted to see how quickly I could make a useful Windows Phone 7 application. I'm not talking about just dragging a button onto a Hello World template and adding "press to fart." I'm talking about an MVP - Minimally Viable Product. It might not be the greatest app in the world, but it will provide value. At least to me.

Disclaimer: I don't work for the Windows Phone Team and don't really know anyone over there. I did this on my own with my personal details, personal account, as an "on the side moonlighting thing." While I work for Microsoft, I work in the Web department, not in Phones.

I honestly hadn't given the Windows Phone too much thought until the "Mango" release, when things got really interesting.

So, last week I sat down and decided to see how quickly I could come up with an app, write it, market it (make a website) and get it in the Windows Phone Marketplace. I had never done any of this stuff and my machine didn't even have any Phone development tools so I was starting from literally Step, ahem, Zero.

The Concept

I am consistently surprised at at how often someone shows me their fancy new phone - no matter what kind of phone they have - and they're using some lame default wallpaper. Folks rarely lock their phones (bad idea) and when they do, there's nothing on the lock screen wallpaper to help them get their phone back if it's ever lost.

"But Scott! I can enable this new fangled GPS and track my phone globally!"

Really? That's lovely and I'm sure ever se helpful when your phone is left in a basement pub, office building, subway or any other GPS-friendly locations. But that's not the point. Why make it hard? If your email or alternate phone number was on your lock screen - maybe even with a reward - chances are you'll get your phone back quickly and easily. Why do I say that? Because I've lost my phone twice before and had a dude call me to pick it up twice before.

I'll make an application that stamps your contact information on custom wallpaper for the Windows Phone 7. My requirements are:

  • Must create lock screen wallpapers that match the Phone's style.
    • The resulting wallpapers must look like a built-in feature
  • Must look actually designed. Correct fonts, alignment, layout.
    • No garish VB3-on-a-phone-green-background-purple-buttons for me.

Cool. I will call it LostPhoneScreen and I pay $8 for the domain. Then I get to work.

Step 0 - Get the Tools

First I go and download the Phone Development Tools. They are free to download, which is cool. To publish an app costs $99 a year though, but I don't have to pay until I decide to publish the app. I can publish up to 100 apps for that $99 and unlimited apps if I pay per app.

If I pay (which I did) I make an account at http://create.msdn.com and put in my bank account information  for when the checks come rolling in.

OK, the Windows Phone SDK is installed so I start looking around for best practices. A development environment is only as good as its community and I don't want to write a bunch of stuff myself if someone has already done the work for me.

Step 1 - Get the Essential Open Source Libraries

My app  has some requirements and some specific technical requirements. I pick these ones because I'm always irritated when apps don't do these things.

  • Must support Mango multi-tasking/quick-resuming
  • Must look nice and layout like a built-in app
  • Must notify (email?) me if a crash happens
  • Must work with light and dark theme
  • Must have a nice About Screen with release notes
  • Must have a nice website to promote that app

I started with these requirements and found these open source libraries and projects to support each requirement.These things are so important that the should have been included in the Phone SDK by default.

LittleWatson

You know when a Windows app crashes and a crash report is sent? That's done by a system called Dr. Watson. Andy Pennell made a small Error Reporting library for Windows Phone 7 called "Little Watson" that was then extended by Bjorn Kuiper and packaged into Bjorn's excellent Northern Light's WP7 Toolkit. His toolkit includes a bunch of little conveniences for serialization, logging and error handling.

It was extremely important to me as a first time app developer (and frankly, it's just important) to get notifications of crashes. I could setup a web service to catch them via HTTP but for the first version, I'll notify the user and email the call stack to me using Little Watson.

MetroGridHelper

Edit screen with transparant grid behind itI found out very quickly when doing resource on phone apps that coding is only maybe 30% of the work. The rest is design. Then layout, then more design. Even for a "trivial" app.

I'm not a designer, but I can follow the basic "Metro design guide for developers" and I see over and over that alignment is king. You know those apps where you look at them and know something's wrong? But you can't see what? Turns out it's usually font size, layout or alignment just poking at the back of your brain.

Jeff Wilcox create a useful debugging assistant that you can just drop into your application with NuGet that will make a set of red squares that are offset 12px from each other with in a page padding of 24px. As you start doing Windows Phone work you'll find that 12px is a magic number and everything looks "right" if it aligns on these boundaries.

I just need to

Install-Package MetroGridHelper

We'll also turn on the FrameRateCounter and only do these things if we are actively debugging.

// Show graphics profiling information while debugging.
if (System.Diagnostics.Debugger.IsAttached)
{
    // Display the current frame rate counters.
    Application.Current.Host.Settings.EnableFrameRateCounter = true;
 
    // Display the metro grid helper.
    MetroGridHelper.IsVisible = true;
...
}

This is so useful it should just be there by default. You'll hear me say that a lot.

SilverlightToolkit

The Silverlight Toolkit from Microsoft is up on CodePlex and also easily installed with NuGet.

Install-Package SilverlightToolkitWP

It include a pile of useful controls like DateTimePicker, LongListSelector, ProgressBar (the one I was interested in), Transitions (another that I wanted), and lots, lots more. These should be in the box. They are utterly essential.

TombstoneHelper

Tombstoning is what happens when you app gets navigated away from then navigated back to. It's how you make your app feel like it's been in the background the whole time the user was switching around, even though you were dead and then came back to life.

Install-Package WP7TombstoneHelper

There's a number of ways to save your apps state, but the I found the WP7 Tombstone Helper useful as it will automatically look at your controls and save their state away then put you right back when you're launched again. It isn't right for every scenario, but it was useful to me.

protected override void OnNavigatingFrom(System.Windows.Navigation.NavigatingCancelEventArgs e)
{
this.SaveState(e);
}

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
this.RestoreState();
}

YourLastAboutDialog

If you're not careful, your About dialog can get more complex than your application. I don't want that, but I do like me a tidy About Dialog. I found YLAD - Your Last About Dialog to be the best option for me. It's a single DLL that gives you a generic but highly configurable about dialog. How configurable you ask?

Look how nice that is!

My lovely about box made with YLADMy lovely history box made with YLADMy lovely credits box made with YLAD

It's entirely managed by a single data.xml file that's totally self explanatory. I especially appreciate apps with clear listings of what's changed between versions. Not enough apps do that, probably because it's hard. But no more! Use YLAD.

Windows Phone Power Tools

Often you'll want to pull files off your emulator or actual phone directly. Since my app is going to serialize settings, make photos, and the like, I'll want to access the file system directly. The Windows Phone Power Tools were essential for accessing my application's Isolated Storage files. It was useful to simulate upgrades from one version to another and to debug serialization bugs.

Windows Phone Power Tools

Another one to watch is IsoStoreSpy that lets you preview files in the app itself.

PNGOut and PNGGauntlet

You will find yourself making a LOT of PNGs when you are doing mobile development. You'll almost always want to compress them before you ship. I squish the PNGs on my blog and often get compression improvements of 30% or more. I squished all the PNGs in my app to make the resulting XAP deployment file smaller, and the PNGs smaller on the phone itself.

I highly recommend PNGGauntlet with PNGOut. No quality is lost as PNG is a lossless image format. It's also worth pointing out that I lived in Paint.NET while making this application. It's an all around great app and the best way to work with all these PNGs.

Portable Library Tools

If you're going to want to create and use some assemblies between projects, the Portable Class Library project template for Visual Studio can make it a lot easier to share code.

Screenshots.cs

It's pretty hard to take a screenshot on a Windows Phone. On an iPhone there is a special button combination, but nothing like that exists on a Windows Phone. However, application developers have to take screenshots and submit screenshots all day long. Enter "screenshots.cs" from the crazy-useful Jeff Wilcox.

install-package ScreenShots.cs

When it's running (you don't want leave it running, just have it going when you need screenshots) it will take a screenshot programmatically every 2 seconds. If you leave it running it'll fill up your phone.  ;)

NotifyPropertyWeaver

When making ViewModels for Windows Phone, you'll always end up taking a nice clean class with some properties and end up littering the properties with code like:

string givenNames;
public string GivenNames
{
get { return givenNames; }
set
{
if (value != givenNames)
{
givenNames = value;
OnPropertyChanged("GivenNames");
OnPropertyChanged("FullName");
}
}
}
And this stresses me out. I don't want to see those OnPropertyChanged and watch my simple class full up with notification boilerplate that I don't need to see. Fortunately Simon Cropp agrees with me and created NotifyPropertyWeaver to add this code post-compilation via IL Weaving without the need for attributes, base classes or even a class reference! It's in NuGet:
install-package notifyPropertyWeaver

Or, even easier, from the Visual Studio Gallery. NotifyPropertyWeaver adds this MSBuild task automatically in your csproj:

<UsingTask TaskName="NotifyPropertyWeaverMsBuildTask.WeavingTask"
AssemblyFile="$(SolutionDir)Tools\NotifyPropertyWeaverMsBuildTask.dll" />
<Target Name="AfterCompile">
<NotifyPropertyWeaverMsBuildTask.WeavingTask/>
</Target>

I realize this whole idea is scary, but I can tell you that I added it and didn't think about INotifyPropertyChanged once in the development of my application. You just add properties and he'll take care of the OnPropertyChanged stuff. If you don't believe him (I didn't) then just open your DLL in Reflector and see for yourself.

My ViewModel class is super basic and I only had to implement INotifyPropertyChanged and the weaver did everything else automatically. Very cool and saved me a bunch of hassle. The details are up on the Google Code site for NotifyPropertyWeaver. I found it a very elegant solution to a potentially messy problem.

Coding4Fun Windows Phone Toolkit

No, the Windows Phone 7 Toolkit isn't enough. Clint and the guys over at Coding4Fun have created a toolkit of their own that adds even more awesomeness (that should have been baked into the thing from the start). Things like Color Pickers, Color Sliders, lots of different buttons and more.

Coding4Fun Windows Phone Toolkit

Drink in the awesome over at http://coding4fun.codeplex.com.

Windows Phone 7 Emulator Skin Switcher

OK, this one isn't essential but it's totally cool eye candy. Why not change your phone skin with the Windows Phone 7 Emulator Skin Switcher? Live a little. The default one that comes with the emulator is a little meh.

When you run it, be SURE to scroll to the right as there are LOTS to choose from.

WP7 Emulator Skin Switcher

It's a nice touch.

Lost Phone Screen inside a Nokia Lumia

There's a great list of other tools, libraries and tips over at Bil Simser's The Big Dummies Guide for Windows Phone Developer Resources. Bil helped me over Skype when I had dumb questions. I'm glad he called his guide the "Big Dummie's Guide" and not the Hanselman Guide because that'd make it too obvious that I was clueless when I called. Thanks, Bil!

All right. I've got the tools and I've got my idea. Now what?

Write The Application

I know C# as I'm an ASP.NET Web programmer, but I'm not a XAML guy. The last thing I wrote in XAML was BabySmash and let's just say it wasn't rocket science. I started by dragging stuff around on the visual designer, pulling in buttons, text boxes and stuff but the XAML source started getting really messy with absolute pixel values and stuff I didn't like looking at. I stared at it for a while and just decided to write the XAML manually via trial and error, convinced that the the simpler the XAML was that more likely my app was laid out correctly. This turned out to be pretty true. I made a home page and an edit page.

Visual Studio and LostPhoneScreen

I got the two pages laid out and focused on making sure everything line up on the 12's (remember the MetroGridHelper I mentioned above) and tried to "intuit" when things looked wrong. I also referred to the "Metro design guide for developers" a lot.

Adding Polish

One thing I couldn't get my head around was that the transition between the main screen and the edit screen seemed jarring. It was like "poof." Then I realized there was no animation. Windows Phone apps usually use short but subtle animations to move between screens. Not just any old animations, but ones that involve direction to indicate moving forward or backward.

I remembered the Windows Phone 7 Toolkit above had transitions, so I applied them. The XAML is scary, but I only had to copy/paste. I made a NavigationIn and a NavigationOut for both pages so that they flip cleanly between each other.

Nice Windows Phone Flip Animation

I changed the PhoneApplicationFrame in App.xaml.cs to a TransitionFrame and the rest was magic. It just worked. Nice.

private void InitializePhoneApplication()
{
if (phoneApplicationInitialized)
return;

//RootFrame = new PhoneApplicationFrame();
RootFrame = new TransitionFrame();

RootFrame.Navigated += CompleteInitializePhoneApplication;

// Handle navigation failures
RootFrame.NavigationFailed += RootFrame_NavigationFailed;

// Ensure we don't initialize again
phoneApplicationInitialized = true;
}

Once this was done, if I needed to add other animations, it would be trivial. This small change made the app feel more polished.

Resources (Yes, more PNGs)

I needed buttons for the ApplicationBar at the bottom but I'm not a designer. I talked to Jin Yang (a designer) to do the main icon:

This sad, tiny phone is lost and on the back of a milk carton. Won't you help him find a home?

ASIDE: If you don't understand this icon, it's because it's apparently not universal. In the US when a child was missing in the 80's and 90's they would put their picture on the back of a milk carton. The idea was that you'd be eating your cereal in the morning and you'd notice the picture and it would seep into you brain so you'd be on the alert for that child during the day. Maybe a "missing" flyer with this phone would be more culturally non-specific.

But I didn't need a full-blown expert for the standard black and white icons at the bottom. The Windows Phone SDK comes with 32 basic icons for things like download, save, stop, play, etc. Even better though are the icons at Templarian. These are hundreds of yummy icons for Windows Phone (and other phones) that are released under the Creative Commons license. The designers name is Austin Andrews and he's super talented. I mean, even when he's just drafting ideas he's awesome. If you use his icons, thank him and tell people. If you are a designer, why not join up and improve the pack for the community?

UPDATE: The 130 icons from WindowsWiki.info are also amazing and high quality. Another great place for icon inspiration is The Noun Project.

My app was so simple that I ended up only using just four of the icons that came with the SDK, but I'm going to exploit the Templarian Windows Phone Icon pack whenever I can in the future.

Interesting Gotchas (actually Got-mes)

The first time I submitted the app it was rejected within two days. Turns out that when you popup a Popup - like for my Save Button - the hardware Back button must dismiss the popup. They are really serious about this model that you move forward and the hardware Back button always moves "back."

I ended up having to close my popup like this:

protected override void OnBackKeyPress(CancelEventArgs e)
{
if (theHelpPopup != null && theHelpPopup.IsOpen == true)
{
theHelpPopup.IsOpen = false;
e.Cancel = true;
}
}

As I continue to explore Windows Phone Development I'm sure I'll find better (read: less hacky) ways to manage things like this. Frankly, I was surprised that the Popup class didn't handle this for me!

Test with Light Theme

Another important thing is to test your app with a light theme. I initially had colors with hard-coded opacity like "CC00000000" for a transparent black. However, when your theme is white-based, rather than black, things start look like crap when you hard code colors. Instead they recommend that you use StaticResources with names that will automatically look correct, regardless of theme:

<Grid Height="448" Width="480" x:Name="LayoutRoot" 
Background="{StaticResource PhoneBackgroundBrush}"
Opacity="0.8">
...

Here I'm using PhoneBackgroundBrush, which means my help Popup looks nice twice!

Lost Phone Screen with Two Themes

However, notice that the black text at the top is hard to read? More on that later. A feature to help with that will be in the next version, which should be out later this week!

Submit the Application

You log into http://create.msdn.com and go through a detailed but largely straightforward wizard. There's a long checklist but the one I spent the most time going over was the Application Artwork for Windows Phone section. You need two different icons for the phone, three different icons for the Marketplace and a panorama in case you are a Featured App. Remember earlier when I said it was less code and more PNGs? This is where the time was taken up; just making sure all the PNGs were perfect from a large source PNG.

After you submit, you wait. I waited 3 days, was rejected, fixed the Back Button issue and Submitted Again.

windowsphoenstep2

Now I've found a few more bugs and will submit an update this week. The cycle will continue.

Attention to Detail

There's so many little things from misspellings to missed pixels that you need to be on the lookout for. For example, I misspelled "wallpaper" in a screenshot - seriously - because I was working late into the night. Sloppy. And now I'll have to wait almost a week to fix it due to the way the Marketplace works. As a web programmer this will take getting used to as I'm used to "hit refresh, it's fixed" when squashing bugs for my users

Triple check everything, test and test again. Every small mistake means 3 days lost waiting for the marketplace to update. And those days can mean days of unhappy users.

Make the "Marketing" Website

Time to make myself a nice simple static website to promote my application. I could hire someone or try to make something myself, but I really just have some basic requirements.

  • The site should include screenshots
  • The site should be mostly static html but feel slightly dynamic (javascript?)
  • The site should work on a mobile device (even iPhones!) using responsive design.
  • The site should link to the Windows Phone Marketplace

I didn't want to spend much time on this, but I also didn't want to do my app a disservice with a crappy site. There are lots of mobile templates out there, but a few stand out as they are Windows Phone 7 Specific.

One is Wp7JekyllTemplates, which works nice if you are hosting your code and site on GitHub. The other is Wp7AppSite by Nick Harewood. I noticed that Wp7AppSite used the Skeleton Boilerplate, which I am a fan of. I used it on http://speakinghacks.com.  It looks great on mobile so I was sold.

It was stupid-easy to setup. I just pointed my domain my my host, setup index.html as the default document, resized the screenshots, modified the HTML and uploaded. Took about 10 minutes.

Pricing

I made it $0.99. I didn't want to make it free because I didn't want to make it free. It costs less than the foam on your latte and it will get nice updates for free. I find it funny that folks will research 99 cent apps for an hour while sipping a $5 latte. ;)

I buy lots of $1 apps because THEY ARE $1 APPS.

Find a Bug

Earlier I mentioned that some wallpapers make it so the text is hard to read depending on the theme. Tim Heuer reported this so I added a feature to invert the text color, as seen in the screenshot below:

Inverted Text in Lost Phone Screen

Notice how the A at the bottom in the Application Bar inverts depending on the color of the text. I am very happy with how that turned out.

Submit the Update

I also removed the progress bar as it was getting in the way of the screenshot process and fixed a data persistence bug where your settings don't always get saved depending on how you exit the application. This is due to my confusion about how task switching vs. application existing works in Mango. That's fixed and will be out as as a free update soon as they certify it.

I'll submit the 1.0.2 update this week that will include the smarter text coloring as seen in the screenshot above. Barring rejection, the Marketplace should notice you'll get the updates!

You can get Lost Phone Screen on the Windows Phone Marketplace and you can offer feedback and feature request on UserVoice. If you buy it, please review it on the marketplace from the About Screen.

UPDATE: Reviews

Bad Reviews hurt, even for a silly little application like mine. I've already released the 1.0.2 update with bug fixes that address many major issues folks have had with the app. Here's what you should do to keep on top of feedback and reviews:

I'll update this post with more info as I learn more. I haven't got download stats yet and I've only just released my first update.

Conclusion

I was pleasantly surprised how easy it was to get into Windows Phone 7 programming. I was also thrilled with the amount of great open source libraries, creative commons art and other resources that are available for the beginner. The marketplace process and website are still a little confusing and rough, and I don't like waiting days to find out how my app is doing, but I guess that's life with a marketplace.

Big thanks to Jin Yang for the Icon and Bil Simser for Skyping with me.

I'll keep updating my little app and trying to think of ideas for my Next App.

Enjoy!

Related Links

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. I am a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.