This is Windows Client Developer roundup #10.
The Windows Client Developer Roundup aggregates information of interest to Windows Client Developers, including WPF, Surface, Windows 7, XNA, Windows Forms, and some Silverlight. If you have something interesting you’ve done or have run across, please send me the URL and brief description via the contact link on my blog.
WPF
XNA
Surface
Cross-Technology (WPF, Silverlight, Surface etc.)
Silverlight
C++ / Native Windows Code
Fun
Another twitter question. As usual, I’m targeting WPF 4 here, but just about everything here works with Silverlight 4 as well.
(read from bottom up)
Let’s say you want to create a standardized “gadget” for your application, from which anyone can derive and create their own gadgets.
The desire:
- Provide a base gadget that has some sort of standardized chrome and some behavior to be inherited by all derived controls.
The challenge:
- Regular derived controls won’t be friendly for your users to create controls
- Regular usercontrols don’t enforce any control template
- Controls inherit functionality/behavior, but not template. Well, technically you do inherit the style and template, but you can’t really override just a part of the template, you have to modify the whole thing, which would let the users mess around with the chrome you’re trying to keep.
There are a bunch of ways to do that, depending on what part you need to standardize, but one of the more interesting is to create your own UserControl-like class deriving from ContentControl. Other options include allowing other people to make their gadgets using anything and you simply host them in a shim control that has the behavior. In some cases, that’s the better choice, but not in cases where you want them to be able to call methods you provide.
The Base Gadget Control
Our base control is simple, but contained in two parts. The first part is the code (the behavior and model of the control). The second part is the visual representation, contained in its style and template.
Control Behavior
Since we’re not providing any other functionality at this point (you can, but I didn’t want to get into Dependency Properties here), the code has only the static constructor required for styling. The constructor says the default style is the one that targets the Gadget type.
public class Gadget : ContentControl
{
static Gadget()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(Gadget),
new FrameworkPropertyMetadata(typeof(Gadget)));
}
}
All the other behavior is inherited from ContentControl. ContentControl is a specialization of Control which allows for a single element to be inserted as content. In a typical UserControl, this single element is the root Grid.
Control Template and generic.xaml
So from where does the Gadget pick up its style? In WPF and Silverlight, there exists the concept of a generic or default style for a control. That style is contained in the themes\generic.xaml resource dictionary for the library inside which the control exists. The name and location are special.
The contents of generic.xaml include styles for one or more controls. The styles contain the control templates which define what the UI of the control is made up of. Since this is a content control, we need to have a ContentPresenter (or another ContentControl) in there, bound to the Content property. Truthfully, you can have anything bound to that property, but if the types don’t match, you’ll get an exception at runtime.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:local="clr-namespace:WpfApplication22"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="{x:Type local:Gadget}">
<Setter Property="Padding"
Value="10" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:Gadget}">
<Border BorderBrush="Red"
BorderThickness="5"
CornerRadius="10">
<ContentPresenter Content="{TemplateBinding Content}"
Margin="{TemplateBinding Padding}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
The TemplateBinding syntax is what you use to bind to properties of the control that the template is applied to.
So, our custom gadget simply enforces a red 5px border around all elements. You could also enforce a background, drag handles, close buttons etc.
The Custom UserControls (Gadgets)
Here are the custom UserControls. I simply added a UserControl to the project, and then changed the markup and codebehind to reference Gadget rather than UserControl. To make it friendlier to your users, I’d recommend creating a custom Visual Studio template for your Gadget. The template would set the base class and namespaces automatically.
First Gadget
There’s also a related code-behind, but it’s empty. In a real app, it’ll likely have code. Here’s the Xaml:
<local:Gadget x:Class="WpfApplication22.Gadgets.TestGadget"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApplication22"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="300">
<Grid>
<TextBlock Text="My Custom Gadget Content"
FontSize="20"
TextWrapping="Wrap"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Grid>
</local:Gadget>
Second Gadget
Similarly, here’s the second gadget’s markup. This control contains an ellipse.
<local:Gadget x:Class="WpfApplication22.Gadgets.SecondGadget"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApplication22"
mc:Ignorable="d"
Padding="25"
d:DesignHeight="300"
d:DesignWidth="300">
<Grid>
<Ellipse x:Name="MyEllipse" Fill="Blue"/>
</Grid>
</local:Gadget>
The Main Window
The main Window contains instances of both gadgets. The highlighted areas of the Window xaml are what are needed to load in our own gadgets.
<Window x:Class="WpfApplication22.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:gadgets="clr-namespace:WpfApplication22.Gadgets"
Title="MainWindow" Height="450" Width="450">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<gadgets:TestGadget Grid.Row="0" Grid.Column="0" />
<gadgets:SecondGadget Grid.Row="1" Grid.Column="1" />
</Grid>
</Window>
Here’s how it looks at runtime:
That’s all there is to it for the basics of creating your own usercontrol stand-ins.
If you’re building add-ins or runtime-resolved Gadgets for your own app, take a look at MEF (Managed Extensibility Framework).
Another (paraphrased) question from twitter “How do I set the minimum and maximum sizes for my window in WPF”. The poster wanted to know how to constrain the size of their WPF window to a set minimum height/width and maximum height/width.
I originally replied with a complex answer referring back to my WPF Resize Behavior, because I completely forgot about the simple supported approach:
<Window x:Class="WpfApplication21.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Height="350"
Width="525"
MinHeight="300"
MinWidth="500"
MaxHeight="700"
MaxWidth="900">
<Grid>
</Grid>
</Window>
The above markup constrains the size of the window to the sizes indicated by using the MinHeight, MinWidth, MaxHeight and MaxWidth properties. You can also set these from code at runtime.
Use this sparingly. It is generally not a great practice to constrain the size of your application window, or at least not the max size.
If you subscribe to my blog (you’re here, and it’s easy, just do it .. dooo itttt ;) click the RSS link above) there’s a Manning deal on my book coming next week. It’ll only be around for one day (Manning sets the terms, not me) and it is a really good deal.
If you haven’t checked it out yet, I encourage you to do so. Some chapters are already available to people who subscribed to the MEAP (Manning Early Access Program) for the book. That program gets you early on-line versions of chapters as well as updates as I incorporate your feedback. With technology that moves as quickly as Silverlight, it really is a great way to get ahead of the curve.
I have two more chapters (5 and 9) which will be on MEAP soon, and the rest in various stages of completion. Overall, the book is shaping up to be larger than originally anticipated, and certainly larger than the original 371 page Silverlight 2 book. I’ve incorporated lots of community feedback about the previous edition, plus Silverlight feedback in general, added to it a huge dose of what I feel is important and have come up with a really awesome book.
Here’s the current table of contents (subject to change, but not likely to):
- Introducing Silverlight
- Core XAML
- The Application Model and the Plug-In
- Integrating with the Browser
- Integrating with the Desktop
- Sizing, Positioning and Transforming Elements
- Displaying Text and Printing
- Human Input and Controls
- Binding
- Validation, Annotation, and Data Controls
- Networking and Communications
- Dialogs, Navigation, and Partitioning with MEF
- The ViewModel Pattern, Testing, and Debugging
- Introduction to WCF RIA Services
- Graphics and Effects
- Displaying and Capturing Images and Media
- Animation and Behaviors
- Styles, Templates, and Resources
- Creating Controls and UserControls
- Distribution and Deployment
This book is being targeted to people who want to dive deep into key areas of Silverlight, learn best practices, as well as just plain lean to work with the technology. I’ve made sure it is accessible to good programmers who are new to Silverlight, but not at the expense of making it a book experienced developers will want.
In short, I think this will be the best all-around Silverlight 4 book out there. I know, I’m humble :)
So subscribe to my blog (RSS link at the top of this page), and then when the deal shows up next week, be sure to take advantage of it.
Disclaimer: If this sounds like a shameless attempt to get more blog subscribers, it totally is. If it also sounds like a shameless attempt to sell more copies of my book, you’re two for two. Humor me, writing a blog and writing a book are both fun, but a ton of work :)
I have an ongoing twitter search for topics of interest to me and my position at Microsoft, so anything with words like “windows forms”, wpf, windowsclient.net etc. all show up in my search. Thought that, I often find folks who are struggling with how to get started in WPF.
I’ve been meaning to do some beginning WPF tutorials for a bit. Since the main focus of my job is to help people be successful with windows client developer technologies, I figured that would be a good idea. Scott Hanselman once described our job as “starting when you hit File->New Project in Visual Studio”
The latest tweet conversation went like this (latest post at top, starter at the bottom)
I show this not to single out Christian, but to show one of the roadblocks folks new to WPF often hit: templating of controls.
If you’re used to Windows Forms or even ASP.NET, where purpose-built controls exist for the common scenarios, doing something as simple as creating a flat image button can be somewhat daunting.
The reason is controls in other technologies focus on discrete scenarios, and try to provide properties to handle every scenario they support. WPF (and Silverlight) controls, however focus on the model of the behavior of the control, not the look and feel. The user interface/experience is completely separated from the behavior and implementation.
Even looking at the diagram, you can see that the xaml-based approach looks more complex at first glance. However, once you realize that all you need is markup to completely change the user interface for the button (not just borders or shape, but everything about its visual representation) you can see how this approach both scales better and is generally easier to use long-term.
I’m not making a value judgment as to which approach is better, but I personally prefer the template model used by Silverlight and WPF over the purpose-built or partially-templatable, or templatable-with-many-assumptions models used in other technologies. I know many of those technologies have made headway to get away from this model, but they weren’t exactly designed with it in mind.
Each of the button controls in the “Many other Technologies” section could have completely different implementations. They may or may not be based on a common base class, and they may or may not expose similar events or commands. The fact that many do is based more on a convention than something enforced in code. Maybe the events are in a slightly different order, or maybe there is some assumed margin or padding. Maybe you can’t hook certain events like a hover without resorting to Win32 calls, and you almost certainly can’t write a single strongly-typed function that will take in all variants of buttons and do something with them. If you’ve ever spent time getting a complex third-party button to behave just like a customized built-in button, you know what I’m talking about.
In WPF and Silverlight, everything which has normal button behavior derives from the ButtonBase class. The most commonly used derivative of that is the Button class.
There are a number of classes in this tree. Looking at them, though, you can see that new classes are created only when new behavior is needed, not when you need a new user interface.
Here is ButtonBase
Here is all that Button adds to ButtonBase.
To throw in a different one, here’s ToggleButton, the immediate ancestor of CheckBox and RadioButton. Note that it adds new behavior to manage checked and unchecked state.
Button is a Content Control
As you can see in the tree above, Button derives from ContentControl. That means Button can contain pretty much anything. We’ll focus on content for most of the rest of this post.
Here’s a Window with a button that contains just some text:
<Window x:Class="WpfApplication19.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Button x:Name="MyCoolButton"
Content="Cool Button"
Width="200"
Height="75" />
</Grid>
</Window>
So, to create a button which looks like a normal button, but contains an image, how much C#/VB code do we need to write? Answer: None. Button is a content control, so we just assign it an image as the content.
<Button x:Name="MyCoolButton"
Width="200"
Height="75">
<Button.Content>
<Image Source="Pete-Brown-Silverlight-in-Action.png" />
</Button.Content>
</Button>
That’s the long form, spelling out Button.Content. The more common form, since Content is, well, the content property, is to omit that and just nest the content directly in the button declaration. The end result is exactly the same.
<Button x:Name="MyCoolButton"
Width="200"
Height="75">
<Image Source="Pete-Brown-Silverlight-in-Action.png" />
</Button>
Similarly, we can assign something more complex, like a grid with an image and multiple rows of text. The content property can have only one element directly contained within it, so compound elements must be contained in something like a grid or StackPanel.
<Button x:Name="MyCoolButton"
Width="200"
Height="75">
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Source="Pete-Brown-Silverlight-in-Action.png"
Margin="5"
Grid.Column="0" />
<StackPanel Grid.Column="1" Margin="5">
<TextBlock Text="Buy My Book!" FontWeight="Bold" />
<TextBlock Text="Pete is writing THE Silverlight 4 book"
TextWrapping="Wrap" />
</StackPanel>
</Grid>
</Button>
Design-Time in Visual Studio 2010
Runtime
Content Alignment
If you want to change the alignment of the content, you can use the HorizontalContentAlignment and VerticalContentAlignment properties inherited from ContentControl.
<Button x:Name="MyCoolButton"
HorizontalContentAlignment="Right"
Width="200"
Height="75">
Left, Center and Right are pretty obvious. There is one more value, Stretch.
Stretch
It looks like the Left-aligned version, but if you look closely at the size of the content grid and stackpanel, you can see they now stretch to fill up all available space inside the button, minus the margins.
Similarly, changing the VerticalContentAlignment will, assuming your content isn’t already taking up all available vertical space, affect it just like the horizontal settings.
Content can be Almost Anything, even other Controls
Just about anything can be used as content for a content control, and the button is no exception. In fact, here’s a really crazy assortment of controls included in the button. (Bonus points if you know the song that starts in the listbox – I’m listening to about 20 remixes of it as I type this)
<Button x:Name="MyCoolButton"
HorizontalContentAlignment="Stretch"
Width="450"
Height="155">
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Image Source="Pete-Brown-Silverlight-in-Action.png"
Margin="5"
Grid.Column="0" />
<StackPanel Grid.Column="1">
<CheckBox Content="Check if you like turtles"
Margin="5" />
<ListBox Margin="5">
<ListBox.ItemsSource>
<sysCollections:ArrayList>
<sys:String>Now how old are you?</sys:String>
<sys:String>Where is your harbor?</sys:String>
<sys:String>Have many things to do</sys:String>
</sysCollections:ArrayList>
</ListBox.ItemsSource>
</ListBox>
<Button Content="Open the Door"
Margin="5" />
<TextBlock Text="Tell me if the sky is blue" />
</StackPanel>
<Image Source="CommodoreLogo_100x100.png"
Stretch="None"
Grid.Column="2" />
</Grid>
</Button>
Sure, that’s totally insane for a button, but it can be done. Imagine what it would take to find controls that natively support this type of content in another technology. Heck, finding a button or other control that would allow you to put in two images seems hard to find.
Changing Colors
Of course, you can change the colors of the button without re-templating the control. Simply setting the Background to a color will work:
<Button x:Name="MyCoolButton"
HorizontalContentAlignment="Stretch"
Background="Orange"
Width="450"
Height="155">
You can set it to a gradient if you want a highlight effect similar to the original button. To do that, we break the Background property out using the property element syntax. This allows us to specify a complex property value, a LinearGradientBrush in this instance.
<Button x:Name="MyCoolButton"
HorizontalContentAlignment="Stretch"
Width="450"
Height="155">
<Button.Background>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<GradientStop Offset="0" Color="#FFAA0000"/>
<GradientStop Offset="0.49" Color="#FFCC0000"/>
<GradientStop Offset="0.50" Color="#FF990000" />
<GradientStop Offset="1" Color="#FF770000" />
</LinearGradientBrush>
</Button.Background>
Ok, so that is one hideous button, but you get the idea. Note that that doesn’t change the hover effect, though. For that, you’ll need to modify the control template, the topic of our next post.

Now what if you want a basic flat button without any re-templating? You can get pretty close by setting colors as well as padding and making sure your button is sized to the image (or is at least using the same aspect ratio.
<Button x:Name="MyCoolButton"
HorizontalContentAlignment="Stretch"
Padding="0"
Background="Transparent"
BorderBrush="Transparent"
BorderThickness="0"
Width="146"
Height="183">
<Grid >
<Image Source="Pete-Brown-Silverlight-in-Action.png" />
</Grid>
</Button>
Note that you’ll still get the default hover effect, though. Since there is some transparency in my png, I can see a bit of it. The hover border will always show unless you have negative content padding.
And yes, as I mentioned above, changing the padding to a negative size will obscure the border. It’s not the most elegant solution, but it works, assuming your content is not set to a fixed size.
<Button x:Name="MyCoolButton"
HorizontalContentAlignment="Stretch"
Padding="-4"
Background="Transparent"
BorderBrush="Transparent"
BorderThickness="0"
Width="146"
Height="183">
<Grid >
<Image Source="Pete-Brown-Silverlight-in-Action.png" />
</Grid>
</Button>
Be sure to check out Part 2 for information on how to template the button control, including setting the handling for the various visual states.
If your Silverlight 4 application is running with Elevated Permissions, you can control a fair number of aspects of the hosting out-of-browser window. You can change the size, location, make it top most, set window state and Activate it. Here’s some simple example code:
if (Application.Current.HasElevatedPermissions)
{
Window win = Application.Current.MainWindow;
win.WindowState = WindowState.Normal;
win.TopMost = true;
win.Height = 200;
win.Width = 200;
win.Left = 150;
win.Top = 150;
if (!win.IsActive)
win.Activate();
}
Of course, use good judgment when moving the window around, or making it top-most.
Robert Iagar on twitter asked how to move a window in WPF without using the built-in title bar or resorting to user32.dll, so I whipped up this quick sample.
So let’s have at it:
Window Xaml
We’ll create a simple window with no built-in border or titlebar. We’ll use a border, some shapes and a HeaderedContentControl to provide stand-in titlebar/content areas.
<Window x:Class="WpfWindowMoveSample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
WindowStyle='None'
AllowsTransparency='True'
Background='Transparent'
Title=''
Height='350'
Width='525'>
<Grid>
<Border Background='Beige'
BorderBrush='LightBlue'
BorderThickness='2'
CornerRadius='10'
Padding='5'>
<HeaderedContentControl>
<!-- New Title Bar -->
<HeaderedContentControl.Header>
<!-- If you want to move using something else, wire up the event there instead -->
<Grid MouseDown='OnDragMoveWindow'>
<Grid.ColumnDefinitions>
<ColumnDefinition Width='*' />
<ColumnDefinition Width='Auto' />
</Grid.ColumnDefinitions>
<Rectangle Grid.ColumnSpan='2'
Fill='LightBlue' />
<TextBlock Grid.Column='0'
FontSize='15'
FontWeight='Bold'
VerticalAlignment='Center'
Margin='3'
Text='This is my custom title bar' />
<Button x:Name='WindowCloseButton'
Grid.Column='1'
Width='25'
Height='25'
Cursor='Hand'
Margin='3'
VerticalAlignment='Center'
Click='WindowCloseButton_Click'
Content='X' />
</Grid>
</HeaderedContentControl.Header>
<!-- New Content Area -->
<HeaderedContentControl.Content>
<Grid Margin='3'>
<TextBlock Text='Content goes here...' />
</Grid>
</HeaderedContentControl.Content>
</HeaderedContentControl>
</Border>
</Grid>
</Window>The main line of interest in this window is wiring up the OnDragMoveWindow handler to the MouseDown event of our titlebar grid.
The resulting Window looks like this:
You can’t move it yet, because we haven’t wired up the event handlers. You’ll also have a hard time closing it since we don’t have the close handler wired up.
Code-Behind
Next we need to wire up the event handler to allow for moving the window around.
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void WindowCloseButton_Click(object sender, RoutedEventArgs e)
{
Close();
}
private void OnDragMoveWindow(object sender, MouseButtonEventArgs e)
{
DragMove();
}
}Note you can also use a command like ApplicationCommands.Close rather than working with an event handler for close. If you’re writing a real application, I suggest you take that route.
That’s all there is to it. If you want to have something else responsible for dragging the window, you simply wire up the DragMove to the MouseDown on that control.
One gotcha has to do with the space the OS normally allocates for the title bar. You’ll notice this if you try and dock the window in Windows 7. The API to address that takes a bit more work, so I’ll address it in a later post.
Last week I had the real pleasure of speaking at the Best of Tech-Ed and Convergence in Reykjavik, Iceland. I was absolutely amazed by the size of the developer and IT community in Iceland, and the turnout at this conference. For an island of about 300,000 people, having a turnout close to 1,200 locals at a conference is pretty amazing.
The participants at the conference were all great folks. Attendees asked both hard and easy questions, and were engaged in the presentations, continuing the discussion into the hallways afterwards. It also helped immensely that just about everyone spoke English fluently as my eight years of French wasn’t going to get me anywhere in Iceland :)
The Microsoft Iceland team was also amazing – they had everything all planned out and treated us as honored guests. The supper on the last night there was an unexpected treat, especially since it turned out two of the waiters were actors playing with us all. :)
Sessions
In addition to wisecracking on the closing panel (hey, no one asked any programming questions :P ), I delivered three regular sessions:
- Silverlight 4 Deep-Dive: The Commodore 64 Emulator
- Lighting up on Windows 7 with WPF4
- Dual Targeting for WPF 4 and Silverlight 4
It’s great to combine so many of my interests into a group of sessions in one event. I got to talk about Windows 7, sensors, gps location, 8-bit computers (yes, I brought my circa-1982 backup computer), hardcore Silverlight, user experience, and upsizing Silverlight applications to WPF. The turnout in the WPF sessions was excellent, with lots of folks interested in continuing to build cutting-edge desktop and web-connected applications.
Folks who attended the sessions and submitted evals will get the slides and demos from Microsoft Iceland once they complete the evals. Some time after that is all done, I’ll post them online as well.
Cool Apps
While there, I also got to interview folks building some great applications, as well as talk to a local consulting company who is working on moving their Windows Forms application to WPF. I’ve have those interview videos up on Channel 9 soon.
Country
The country itself is absolutely beautiful. I’d love to visit again and dedicate a couple days to taking a good look around and really taking in the glaciers, waterfalls, geysers and all that Iceland has to offer.
On the last day there, before the late afternoon flight, Tim Heuer and I took a walk around Reykjavik and checked out the sites and shops. Of course, we both tried out the famous Icelandic hotdog that Clinton made even more famous. We also visited the famous Hofthi house where, among other things, Reagan and Gorbichev met to start the end of the cold war.
As you can tell in the photos, it was rainy and cloudy for most of the trip. Amazingly, it was much colder and snowier here at home. Iceland remained around 40F the whole time – shorts weather!
BTW, Coke is everywhere. I’ve never seen so much red and white. Their coke is much better than ours though, using cane sugar and served in glass bottles. I have no idea what the sweetener in Coke Light was, but it tasted much better than Diet Coke. Why do we always send the good stuff overseas?
IcelandAir
The trip back on IcelandAir was bumpy but otherwise uneventful. I was able to get an inexpensive upgrade to the “Comfort” section of the Economy class. That gave me a little extra leg and arm room plus a power outlet, so I was able to get a good part of the next chapter in my Silverlight 4 book written.
Unfortunately, when they did that upgrade, IcelandAir exchanged my connecting UsAir ticket from Boston to Washington, DC for …. nothing. I almost ended up having to spend the evening in Boston, but a last minute runner (literally a runner) came over to the ticket counter in Boston with the exchanged ticket and I made it to the shuttle flight just before the doors were closed. Phew!
IFE
The in-flight entertainment system (a Thales IFE i4500 touch screen) was nice, but the touch screen was absolutely horrible – on both flights, so this wasn’t a fluke. The instructions said you had to hold your finger on the button for “two seconds, and do not press multiple times”. It was pretty finicky at best. It did its job, but the touch screen – the one real interface with the passenger – just stank considering how recently it was installed.
I did like the cool map, though.
Overall
I’d definitely go back to Iceland again, especially if invited to speak. The community is great, the hosts were awesome, and the country is beautiful. Highly recommended.
This is Windows Client Developer roundup #9.
I’ve returned from a great time in Iceland. Awesome community and incredible place to visit.
One item of note: If you want to see the WCF RIA Services source code shipped with the product, be sure to vote in this poll.
New blog from the WPF/Silverlight designer team. Check it out.
The Windows Client Developer Roundup aggregates information of interest to Windows Client Developers, including WPF, Surface, Windows 7, XNA, Windows Forms, and some Silverlight. If you have something interesting you’ve done or have run across, please send me the URL and brief description via the contact link on my blog.
WPF
Windows Forms
Cross-Product (WPF, Silverlight, Surface, etc.)
Fun
This is Windows Client Developer roundup #8.
I’m off in Reykjavik Iceland this week, speaking about Silverlight and WPF, but put this together ahead of time to ensure we have some great links for this week.
By now, you’ve probably heard that Visual Studio 2010 and .NET 4’s launch date is April 12, 2010. The teams are doing more performance work to ensure we all have the best possible experience with the tooling and libraries. I, for one, am glad to see the focus on quality over sticking to an arbitrary release schedule.
The Windows Client Developer Roundup aggregates information of interest to Windows Client Developers, including WPF, Surface, Windows 7, XNA, Windows Forms, and some Silverlight. If you have something interesting you’ve done or have run across, please send me the URL and brief description via the contact link on my blog.
WPF
Cross-Product (WPF, Silverlight, Surface etc.)
Windows 7 (and Windows in General)
Surface
Silverlight
Fun Stuff
I code for fun.
When I was quite a bit younger, it was pretty early in the era of personal computers, pre-PC revolution. I’ve been pretty clear about how much I loved my Commodore, so I won’t drone on and on about that here (you may breathe a sigh of relief now, but this post reads well with the theme from M.U.L.E. or better yet, a remix of Outrun playing on your headset). Back then, our personal devices – Walkman, early (and crazy expensive) scientific calculators, and…umm.. well crap, there wasn’t much else of interest to carry around other than rubik’s cubes and rabbits foot keychains... anyway, back then, those devices were fixed, you couldn’t really enhance them unless you wanted to start soldering boards.
They were limited by what a small number of designers and engineers thought they should do -- that was the extent of their capabilities.
It’s not like you could write a codec and suddenly your walkman could play DAT cassettes.
Even if you did do some soldering, the possibilities were pretty limited. Later, when I was finishing up high school, programmable scientific calculators that ran a tiny version of BASIC started appearing, but they were limited and (let’s face it) supremely dorky – carrying one around was pretty much an invitation for people either to kick you across the schoolyard, or follow you around like a lost puppy, hoping you’ll cough up the math homework answers before 6th period.
It was easy to get in to programming because for programming, you basically had just computers. You could go super deep on a single platform and form factor. However, the experience was very limited by that fact.
Programming was a sit-down desk-oriented hobby, and if you wanted to show someone what you had done, you either had to hook up ye old 800 pound VCR to the C64 video output (loved that) and bring a tape to show your friends, or drag people over to your computer so they could nod and pretend they understood just how much effort you just expended to make that ball bounce around the screen. Sometimes *gasp* you would just print all the stuff out on beautiful fanfold (crinkled and half-separated on one side from jamming, of course) and show people your printouts. Sometimes you’d upload stuff to a BBS, but there was no always-on internet connection to use to show people what you’ve done, and screenshots weren’t exactly friendly to 300bps modems.
So, it was fun. You programmed for computers, often just for the sake of doing it. The stuff wasn’t portable, so you were forced to stick to the bedroom/den/basement/dungeon or wherever you coded.
Today though, it’s a different story. It seems like everything and everyone is coming out with APIs and SDKs for their devices. You can code for pretty much all the devices you’d care to. In fact, if you manufacture or run something useful as a device or web site and don’t have an API or SDK, you severely limit your product growth as 3rd party and consumer-written apps are killer (iPhone and Windows are both proof of that).
Virtually every phone we carry can be programmed. Initially you had Java and C++, later .NET and with the iPhone, ObjectiveC (and MonoTouch/.NET). With the Android you can do pretty much whatever you want to the OS, assuming the carrier hasn’t locked you out, and with the upcoming Windows Phone and rumors of Silverlight on same, we can all build some awesome apps. You can write code for something in your pocket, carry it around and make use of it in the supermarket (not to buy brussel sprouts), club, whatever.
While most of those devices are computers in all but name, we’ve also got netbooks for dirt cheap that are as small as a hardback book, a third as thick, and weigh even less. They’ll run most modern operating systems and let you code on them using just about whatever you want. It’s your whole development studio or design portfolio, and fits in a purse (or, umm, a man purse, I guess, not that I’d know <g>)
Back when I actually had time to play video games on a console, it was all a closed system. There were hacks to create your own trusted cartridges without paying royalties and signing huge contracts with the console vendor, but it was a real chore to find the info and program the chips. Today, if you want to write games to run on your Xbox, all you need is .NET and XNA and membership to a very open creator’s club. It encourages exploration and experimentation, and helps provide a huge audience of people to try out your stuff.
The developer community makes it better.
We have microcontrollers like the Arduino, robotics like Lego Mindstorms, watches that run micro frameworks, desk phones with full computers embedded in them, smart panels, programmable homes, and now an ebook reader (Kindle) that too has an SDK so you can write your own casual games or whatever else you want to run on it. No one bought the Kindle thinking it was a development platform, but Amazon has decided to make it into one, make it far more useful than just a book reader. It will break out of the world of product designers and engineers and grow in directions perhaps unconsidered by the manufacturer.
Entertainment centers are as programmable as desktop computers (assuming DRM and “trusted paths” don’t get in your face), and today’s equivalent of the walkman (Zune etc.) can run most any code you throw at it. Zune will even let me run my .NET code using the same development environment and libraries as the Xbox.
The proliferation of developer-friendly devices is a bit like Mozart waking up one morning and finding out that anything can be an excellent musical instrument as long as you tell it the notes to play – no other artists required.
Or perhaps more appropriately, it’s like my kids just found out they can color on any wall they want.
That’s awesome :)
Windows 7 introduced the Sensor and Location API. I’ve previously blogged about the sensor API, but couldn’t wait to get into the Location side of it.
Location API Overview
The location API is a specialized part of the overall sensor API. Many portable devices, laptops and tablets are starting to include GPS and WIFI equipment, both of which can be used to idenfity your current location. Given the ubiquity and interest in it, location was important enough to break out from the rest of the API to enhance usability and discoverability.
(image source MSDN)
There are multiple flavors of location data. First is the default location data set in Windows 7. If you write an application that uses the Location API, and the user has no location devices, and has not previously entered a default location, they will be automatically prompted:

The default location is the fallback location for sensor-less machines. It also tends to work best on stationary PCs, as you’d have to update the address information otherwise. The second type of information is coordinate (latitude/longitude) information. We’ll cover both after we deal with initializing the device.
Starting a Provider (or Watcher)
To use the location API, you simply create a new GeoLocationProvider (changed in RC/RTW, see note at the end of this post) and hook the appropriate events. The first event of interest is the StatusChanged event. That will tell you if the device is ready, or you lose signal etc.
GeoLocationProvider provider = new GeoLocationProvider();
provider.StatusChanged += (s, ev) =>
{
StatusText.Text = ev.Status.ToString();
};
// other events here
StatusText.Text = "Waiting for data...";
provider.Start();To start reporting data, call the Start method.
Once you have the device wired up and ready, you may want to capture the address information.
Civic Address Location
Accessing the address location information is pretty simple. In Beta 2, use the LocationChanged event on the GeoLocationProvider.
provider.LocationChanged += (s, ev) =>
{
StringBuilder builder = new StringBuilder();
builder.AppendFormat("Address1: {0}\n", ev.Location.Address.AddressLine1);
builder.AppendFormat("Address2: {0}\n", ev.Location.Address.AddressLine2);
builder.AppendFormat("Building: {0}\n", ev.Location.Address.Building);
builder.AppendFormat("FloorLevel: {0}\n", ev.Location.Address.FloorLevel);
builder.AppendFormat("City: {0}\n", ev.Location.Address.City);
builder.AppendFormat("StateProvince: {0}\n", ev.Location.Address.StateProvince);
builder.AppendFormat("CountryRegion: {0}\n", ev.Location.Address.CountryRegion);
builder.AppendFormat("PostalCode: {0}\n", ev.Location.Address.PostalCode);
LocationText.Text = builder.ToString();
UpdateDrawing(ev.Location);
};On my machine, since I only have the zip code in the default address, that is all that is reported here.
More interesting than address, for this example anyway, is the coordinate location returned from the GPS.
Coordinate Location
Coordinate location (lat/long) is what I was most interested in playing with. It’s important to note, though, that both lat/long and address are part of the same overall location API, and can be used in similar ways in your own applications.
If you’re looking for a GPS that will work with the API, pick up a copy of Microsoft Streets and Trips 2010 – the one with the black UBlox GPS included. You can then download the Win7 driver for that from http://www.ublox.com/en/usb-drivers/windows-7-driver.html
For my own sample application, that’s what I used. The device reports lat/long and timestamp as you move about. If you use it, I recommend using the extension USB cable (or better yet, get an extension that is both longer and has a firmer grip) in order to minimize interference from the laptop. Some laptops emit enough interference that it makes it next to impossible to get a signal. The reason I recommend a cable with a firmer grip is because the GPS dongle easily pulls out of the extension cord. You could use tape or something to remedy that, but as I mention below, you’ll probably want a longer cable anyway.
The reason you’ll want a longer cable is to allow you to stick the sensor (assuming this is in your car) up on your dash or window and keep the laptop somewhere like the console or the seat next to you. The little cable that comes with streets & trips is barely long enough for that in my Odyssey.
The other thing you’ll want to do is get some sort of velcro or sticky back to keep the usb dongle up on your dash. The device weighs almost nothing and the USB cable easily drags it down off the dash – especially when you’re flying around the corner, not watching where you’re going because you’re looking down at the screen on your tablet while your son in the back seat is asking what the heck you’re doing with that computer in the car ;)
Anyway…
Getting lat and long is really simple. My main bit of advice for you here is to try and minimize the churn by making sure you’re far enough away from the last reported lat/long to care about it. This is important when plotting points or otherwise working with the data. The GPS reports lat/long so often that unless you’re on the highway going 100mph (again, not that I’d do that, heh) the distance changes can be pretty minute.
Back to the LocationChanged event, plug in this code to get the coordinates, heading and speed (the ublox dongle only reports the coordinates, you can calc heading and speed)
builder.AppendFormat("Latitude: {0}\n", ev.Location.Coordinate.Latitude);
builder.AppendFormat("Longitude: {0}\n", ev.Location.Coordinate.Longitude);
builder.AppendFormat("Heading: {0}\n", ev.Location.Heading);
builder.AppendFormat("Speed: {0}\n", ev.Location.Speed);So, I put that all together and built a little WPF 4 application that shows your position on a grid. I inverted my Y axis, unfortunately (math kills me every time), but otherwise it worked great. I call it “GPS Etch-a-Sketch”

I put the Dell XT2 tablet in the Odyssey and drove my son to his gym class at Rolly Pollies. On the way back, I captured the activity in Camtasia, and also snagged this screenshot. On this machine, I have no default location information (not even a zip code) but was not prompted for any since I did have a location reporting device attached.
The red half-moon in the middle of the track is a rendering artifact. I think it’s the video driver in this Dell, or it could be a result of running this with Camtasia on.
Here’s the video (available starting around 2:30pm 1/23/2010), sped up to 800% so you didn’t have to live through 20 minutes of driving, including all the stop lights and the Arby’s drive through (with the speed-up, I couldn’t resist sticking the Benny Hill music in there <g>)
Here’s the code I used for plotting the points (lines, actually) on the window
private void UpdateDrawing(GeoLocation location)
{
if (!double.IsNaN(location.Coordinate.Latitude) && !double.IsNaN(location.Coordinate.Longitude))
{
if (!_firstReading)
{
// plot a line from last point to this one.
Point plotPoint = TranslateLatLongToScreenPoint(location.Coordinate.Latitude, location.Coordinate.Longitude);
// avoid plotting the same 1pt lines over and over
if ((int)Math.Round(plotPoint.X) != (int)Math.Round(_previousPoint.X) &&
(int)Math.Round(plotPoint.Y) != (int)Math.Round(_previousPoint.Y))
{
Line line = new Line();
line.X1 = _previousPoint.X;
line.Y1 = _previousPoint.Y;
line.X2 = plotPoint.X;
line.Y2 = plotPoint.Y;
// TODO: vary thickness or color by speed. If not varying, can use a polyline instead
line.StrokeThickness = 3;
line.Stroke = Brushes.Green;
// add the line to the plot area
PlotArea.Children.Add(line);
// setup for next line
_previousPoint = plotPoint;
}
// move the turtle and set its heading (TODO)
Canvas.SetLeft(Turtle, plotPoint.X - Turtle.ActualWidth / 2);
Canvas.SetTop(Turtle, plotPoint.Y - Turtle.ActualHeight / 2);
}
else
{
_firstReading = false;
_startingLatitude = location.Coordinate.Latitude;
_startingLongitude = location.Coordinate.Longitude;
// calculate top left corner of plot area by figuring out the center
_plotAreaTopLeftLatitude = _startingLatitude - ((PlotArea.ActualHeight / 2.0) / PixelsPerDegreeLatitude);
_plotAreaTopLeftLongitude = _startingLongitude - ((PlotArea.ActualWidth / 2.0) / PixelsPerDegreeLongitude);
// calculating the prev point after calculating top left will effectively center the plotting
_previousPoint = TranslateLatLongToScreenPoint(location.Coordinate.Latitude, location.Coordinate.Longitude);
#if DEBUG
// if algorithm worked, this will be 0,0
Point debugPoint = TranslateLatLongToScreenPoint(_plotAreaTopLeftLatitude, _plotAreaTopLeftLongitude);
System.Diagnostics.Debug.WriteLine("Top x={0}, y={1}", debugPoint.X, debugPoint.Y);
#endif
DrawBackgroundGrid(_previousPoint);
}
// store new coordinates as last old coordinates
_previousLatitude = location.Coordinate.Latitude;
_previousLongitude = location.Coordinate.Longitude;
}You can see that on the first reading from the GPS, I identify the center of the drawing (the start point) and draw the grid. I also set up the lat/long of the top-left based on all that.
My TranslateLatLongToScreenPoint function is messed up on the Y axis, so I’ll refrain from posting the code here.
Finally, here’s the Xaml. Rather than monkey around with z-order, I just created three different canvasses for me to draw on: the background (grid lines), plot area (the green dots/lines) and the overlay (the red circle). Also, to keep the background lines sharp, I turned on SnapsToDevicePixels.
<Window x:Class="LocationDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
WindowState="Maximized"
SnapsToDevicePixels="True"
Title="GPS Etch a Sketch"
Height="700"
Width="1200">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="275" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Margin="5">
<TextBlock x:Name="StatusText"
FontSize="14" />
<TextBlock x:Name="LocationText"
FontSize="14"
TextWrapping="Wrap"/>
</StackPanel>
<Canvas x:Name="BackgroundArea"
Background="White"
Grid.Column="1">
</Canvas>
<Canvas x:Name="PlotArea"
Background="Transparent"
Grid.Column="1">
</Canvas>
<Canvas x:Name="OverlayArea"
Background="Transparent"
Grid.Column="1">
<Ellipse x:Name="Turtle"
Width="15"
Height="15"
Fill="Red"
Opacity="0.75" />
</Canvas>
</Grid>
</Window>Important RC / RTW Changes
Note that the information here applies to Beta 2. Gavin Gear blogged about upcoming changes in the rc and release of .NET 4. Here are two diagrams from his blog.
Current (Beta 2):
Planned (RC/RTW):

Those changes make a lot of sense since the Address information, reported in every update event, doesn’t change like the coordinate information does.
I’ll update this application (fix some bugs and otherwise clean it up) and post it as a sample after RTW. I don’t want to put a real sample out there using the Beta 2 API.
Prior to joining Microsoft, I worked at a consulting company for a bit over 13 years. Prior to that, I started the IT department at a medical billing company and worked there for 4 years while completing my Computer Science degree.
Seeing Scott’s post on past work he did years ago at SparkFun and 800.com got me to thinking about some of the interesting projects I’ve been on. I’ve been a developer, a designer, an architect, a project manager, an engagement manager covering multiple projects, and an analyst. I was happiest, though, when I could get my hands on the code and visual design :)
One thing that was interesting about consulting vs being in internal IT, is your problem domain changed every two to nine months. I met new clients, had to solve new problems and understand a new business on a pretty regular basis. Often times, I’d be on multiple projects at the same time, so it was even more of a stretch.
So here are some interesting ones, in roughly chronological order. No, this isn’t a resume, just some interesting cherry-picked stuff :)
Before I joined Microsoft, I worked for AIS, and before that, I worked for a medical billing company in Massachusetts, so we’ll start there.
Doctor’s Office Billing System – C++
My first application I wrote professionally was a Borland C++ 3 (DOS) medical billing program. I bought a book on how to write a database using C++ – it was all about b-trees and interesting data structures, and wrote the whole thing. It worked reasonably well, had a good dos-based character mode windowing library, and was a decent performer. That was a crapload of custom database code, but I didn’t know any better.
Doctor’s Office Billing System – dBase IV and FoxPro 2.x
Once I realized I didn’t have to write databases from scratch, I used dBase to write the next office billing program. When I moved it to foxpro and added sql statements into the mix, the performance went through the roof. To this day, this is still the fastest database application I’ve written. It was blazing, and the UI was awesome.
Medicaid Billing Program – VB3/VB4
When I started programming in Windows, I tried Delphi 1.0, PowerBuilder 3, Gupta SQL Windows, Borland C++ with OWL, and Visual Basic 3. The company I worked for at the time felt programmers should buy their own tools just like carpenters so that was a fair outlay of cash to get started, all while still in college. I liked learning all the different tools, though.
While I still have, in production, a Delphi 1.0 app (just found out about that the other day – amazing!), I was most proud of a VB3 app I wrote for UB92 Medicaid billing. It was one great big data entry app with an access database, and an exporter that wrote out Medicaid flat files for writing on a big old tape for submission.
Cruise Ship Group Reservations System – VB4 + COBOL
My first project when I joined AIS was to travel to Miami every Monday and fly back home to Maryland every Friday during the months of June through October. If you’ve ever been to Miami at that time of year, especially if you were a pasty white yankee fresh out of New England like me, you know that’s a rough commute.
The project was interesting. I did UI work in VB4 for the group reservations system for a cruise line. The application connected to a Unisys mainframe and used “stored procedures” written in COBOL. All in all, pretty neat, and my first taste of large-scale application development.
Course Materials / Demos for Intro to VB in French
During December 1996 I traveled to Lille, France for two weeks to teach Visual Basic to a bunch of COBOL programmers. Before I left, I was told I was going there to write some demos. It wasn’t until I arrived that I was told I was to teach a class on VB, in French. My French picked back up in the second week (takes me a week to get immersed) and it went pretty well.
Law Enforcement Evidence Management System – VB4/5 + ASP.NET
Another project in Florida. I’m not sure why I kept getting assigned to Florida-based projects, but hey. This one was pretty neat: a complete evidence management system for the Florida Department of Law Enforcement. The strange thing was the customer had a legislative mandate that it had to be a “web app” – no questions allowed. However, they wanted to do a bunch of desktop integration (automate Word and Excel) as well as have a rapid data entry experience, and integration with a hand held barcode scanner.
This was around the time ASP was first released, and browser apps just weren’t up to the task. What we ended up doing was bundling all the client-side code into activeX controls, and surfacing them through the browser. The users decided they didn’t like the browser chrome, so we had to host a browser control in a VB shell, and then do some hackery to wire up the shell menu system into the browser control and into the activeX controls. Major mess just to meet a misguided mandate.
In the end, due to changing requirements and team attrition, I wrote almost all of the VB code for this application.
Pension Management System – VB6
One of the largest VB applications I ever worked on was a pension management system that used VB6 and (I believe) MTS. Could have been COM+ but I think it was MTS. Back end database was a unisys mainframe using COBOL “stored procedures”
The interesting mandate in this app was I had to write a VB6 framework that would allow client non-programmers who wanted to be programmers (ack!!) to enter in the transaction details, business rules etc. without getting too deep into the architecture.
The solution ended up being a ton of code generation via a custom code generator I wrote for Rational Rose, a custom dataset replacement that had a lot more built-in functionality, and templates that basically had “insert code for X here”. It was successful in the end, but surely would have taken a lot less time to build if not for the desire to allow non-programmers to participate in programming.
.NET 1.0 alpha/beta 2 Day Seminar
Another education task. I gave something like 10-15 of these around the country. In the .NET 1.0 alpha days (when everything was still changing) I did a 2 day seminar using Microsoft-provided decks and demos (which you had to keep modifying to keep up with the bits) showcasing all the major features in .NET. It was all about showing VB6 programmers how cool .NET is, and doing the same for classic ASP programmers. Lots of demos of brand new and exciting technology.
Healthcare Vaccine Clinic Scheduling App – ASP.NET
For this ASP.NET application, I did overall UI design, use-cases and modeling work. I didn’t do much code, and that was a first. This was also the first project where I ended up taking on formal managerial duties.
Stock Trading Regulation Enforcement Reporting Application – ASP.NET and XSLT
Back when it was still called NASD, I wrote an ASP.NET application that was used to show data from a bunch of different systems in a common format. It had to be written so that other systems could be added without requiring changes to source code in the application. I ended up doing a bunch with config files and fairly large custom XSL transforms to allow plugging in various different data sources and get meaningful data from them. The client wrote the (convoluted and huge) SQL statements but otherwise this was a fun little one-man project for me.
Education Bookstore eCommerce Site – ASP.NET 2
Sometimes we got called in to clean up other people’s messes. This was one of those times.
This company had an architect working on an ASP.NET application for a year and a half, unchecked, with no oversight. A month before they had to go live they finally decided to see where the application was. The architect had finished about 3/4 of a completely custom framework that tossed out almost everything in ASP.NET and replaced it with his own patterns. The framework, though, met exactly 0% of the business requirements, as there was no app to show.
On this I led a team and also did a ton of ASP.NET coding. We tossed out the custom framework, went straight to in-box functionality – working 15 and 20 hour days, and a number of 24 hour days, and got the online bookstore up and running just in time to meet the summer demand period. You see, they existed as the online bookstore for schools and universities, and if they weren’t live in early summer, they were out of business. We cut this so close that we were taking orders on the site before the credit card charging part of the application was completed. It took about a week before the CC charging bits were done and cards were actually run and charged.
This turned out to be a fairly ungrateful client in the end, but I was really happy with what we accomplished here. I can truthfully say that my team saved this company from going out of business, and that’s a feel-good thing for sure :)
Auto Glass Claims Counselor App – .NET 2 Windows Forms + COBOL
Around the early .NET 2 timeframe, I worked on a Windows Forms project for a large insurance company who happens to have a green mascot. I did mostly the UI and a little back-end on this.
This was the project I always tell people about where the client wanted a UI that looked cool and modern, but couldn’t get capital budget for 3rd party controls. They decided there was less friction in having me do a ton of custom painting for windows forms controls since that was coming out of a staffing budget and didn’t require such a big approval process.
Mobile Phone Store – ASP, ASP.NET, C#, .NET 1.1 and 2
One of my almost purely management projects (I had 11 team members) was for an online Mobile Phone Store for a major electronics retailer, though a company that did all the actual selling and fulfillment for the phones. The platform the team had to build on was set, we “just” had to augment it with a bunch of new functionality, new skins etc. The platform was an interesting combination of ASP.NET that then called a checkout process in classic ASP, and then bounced back to ASP.NET. Oh, and the ASP.NET code was in the process of being converted from 1.1 to 2.0, so that was extra fun :)
The project was a success and the customer and the electronics retailer were both very happy with the results and the process. While this customer went through a bankruptcy process much later and have a different name now, they were always good folks to work with.
For this same customer, I ended up doing some Amazon.com integration work later. That was my first exposure to the hot mess that is the amazon catalog and partner system. I only hope it has gotten better since then.
Carbon Calculator – Silverlight 1.1 Alpha
My first foray into RIA was with Silverlight 1.1 alpha. I and a colleague built the Carbon Calculator for Conservation International. While the app was functional, it was ugly, and this was my first experience with hitting the limitations of my own design abilities and deciding future projects would need a real designer.
You can see some info and screenshots of the calculator here.
I’m happy to say, though, that this project cemented my interest in Silverlight. Also, due to the permission I got to deploy the app into production, it also let me say we had the first and only Silverlight managed-code application in production at the time. I’ve always taken pride in that.
MSDN East Coast News – Silverlight 2
MSDN East Coast News is a Silverlight 2 app that I built (through AIS) at the request of some of our local DPE folks. I had some availability, and was the only person willing to put in a bunch of my own time, so I did this one solo.
This was the first time I did any Facebook integration. Of course, it was also done at the time Facebook was changing their API and the application screen layout. What a mess that was.
I’m pretty proud of the app I designed and built here. It worked well and did most of what we envisioned. This is also the app I used to develop some of the early patterns I used in other Silverlight applications. You can find more information on it here.
Document Search Application – Silverlight 3 in SharePoint
One of the last applications I worked on at AIS was a SharePoint document search application. The customer wanted Silverlight for the rich UI, but more importantly, for speed and document/index caching. This customer has field reps who are often on the other end of a very slow dial-up connection, so they needed to pre-seed their laptops with index data, and have a good way to incrementally update that to allow document searches that were much quicker than the all sharepoint approach. They also wanted to experiment with other ways of visually classifying the data and otherwise augmenting the search.
On this project, I worked with the customers design team for the UI. I did all the initial UX work (with them in the room) using SketchFlow pre-release bits on my laptop, and then walked them through wireframes and a progressively higher fidelity prototype. The visual design team then took the screens we all came up with, and made them look SOO much better. They were involved from day 1, so they knew the UX, and the types of constraints we had to work within. It was a good experience all around.
I wasn’t there for the completion of this project, but I left it in very good hands.
Of course, in 17+ years of work there are quite a few other applications and projects I left out (not counting all the things I did on my own), but those are the ones that always stand out in my mind. Since I don’t actually write applications for a living any more <g>, I figured I’d put this list in web-cement for future generations of computer nerds to marvel at :)
This is Windows Client Developer roundup #7.
The Windows Client Developer Roundup aggregates information of interest to Windows Client Developers, including WPF, Surface, Windows 7, XNA, Windows Forms, and some Silverlight. If you have something interesting you’ve done or have run across, please send me the URL and brief description via the contact link on my blog.
WPF
Cross-Product (WPF, Silverlight, Surface etc.)
Fun Stuff
I subscribe to maybe a hundred blogs, most of which are related to programming or design. To keep it mixed up, I do have a bunch that I read every day just for fun. Here they are, in alphabetical order. Take a peak through, and if you find some you like, go ahead and subscribe. If there are some you sub to now that I don’t have listed here, let me know in the comments – I’m always looking for new stuff.
| AwkwardFamilyPhotos.com They’re there, just lurking in your photo albums: those horrible 80’s and 90’s photo poses, those family members with mullets and crossbows, young children reading the Exorcist. Relive the awkwardness here. | |
Boing Boing The News Feed for Geeks. This is just a ton of random stuff that can be interesting or terribly boring. It’s updated pretty frequently, and is skim-friendly. | |
C64 Walkabout If you’re a C64 fan, you’ll want to subscribe to this blog and podcast. The blog has tons of great bits of info, and the podcast is a lot of fun to listen to. Kudos to these guys for putting together such a great site dedicated to the bestselling computer of all time. Be sure to subscribe to the podcast too. You’ll enjoy it. | |
Dilbert Daily Strip Dilbert comic in your RSS feeds daily. If you’ve ever worked in a cube farm, you’ll love Dilbert | |
Engadget Engadget usually has great info on the latest tech products and news. Their site is a little ad-heavy and distracting, but the RSS feed is just right. | |
Epic Win FTW In contracts to the FAIL Blog, Epic Win FTW showcases pure awesomeness | |
FAIL Blog If you’re the type to laugh out loud when the person next to you trips on the sidewalk and splits open their face, this is the site for you. Fails of all sorts from the minor to the truly epic. | |
Gapingvoid Interesting posts in an almost Ira Glass-type sarcastic tone, but angrier. Sometimes fun. | |
Oddly Specific Signs signs everywhere signs. But not just any signs – signs that are bizarre in their specificity or the message they’re trying to convey. | |
Offbeat Earth Always something interesting here, and not too spammy with the posts. | |
People of Walmart When you were younger, did you sit around the mall poking fun at people as they walked by? Do you do it now? Did you ever gasp when you saw the hideous outfit someone was wearing in the store? This is the site for you. Mullets. People dressed as pimps, animals, and in clothes that are just plain wrong, if you can even classify them as clothes. Oh, and people doing just plain stupid stuff in the aisles of Walmart | |
Probably Bad News This site is full of badly reported news. It’s funny in the “roll your eyes and be glad you get news from multiple sources” kind of way. | |
RAILBRICKS Super-detailed LEGO trains. ‘nuff said. | |
The Oatmeal Funny, well-written and always easy on the eyes. Punch a dolphin for me. | |
This is Photobomb Have you ever looked at a photo after you developed it or uploaded it to your PC, and found something unwanted in it? Like someone making a face in the background, or a bunch of guys standing around with aprons printed with ….umm… sausages on them? You’ll find it here. | |
Urlesque A little bit of everything from the internet. Great blog that always has something interesting. | |
xkcd A comic for geeks and science/math geniuses everywhere. My favorite comic on the web – and I’m not a science/math genius :) | |
| You Drive What? Way over the top vehicles that folks see around town. From the action figure car, to the oddly pimped out snack food product placements to the catbus from Totoro. It’s all here. | |
Have any interesting feeds I missed? Post them in the comments below.