One of the controls I felt was missing out of the box for the Windows Phone 7 was a Notification control similar to how Toast notifications are displayed. As part of an application I'm working on I need a control like this with some of the animation effects the toast has.

On a side note the Coding4Fun Toolkit has a more fully featured control but lacks good view model integration (to be fair 90% of controls do).
It has three properties, Title and Text (I'll most likely be adding an icon at a later date) are fairly self explanatory, the third OnDimiss is a callback when the notification is dismissed by a tap.
<controls:Notification x:Name="Notification" />
From the code behind it displayed with the following calls.
private void OnDisplay(object sender, RoutedEventArgs e)
{
Notification.Display("Title", "Text", () =>
{
MessageBox.Show("Dismissed", "The notification control has been dimissed", MessageBoxButton.OK);
});
}
private void OnDismiss(object sender, RoutedEventArgs e)
{
?Notification.Dismiss();
}
From a view model we can expose a unit testable notification source and bind that to the control.
public class NotificationViewModel
{
public NotificationViewModel()
{
Notifications = new NotificationSource();
}
public INotificationSource Notifications
{
get;
set;
}
public void Display()
{
Notifications.Display("Security", "Tap to authenticate the application", () =>
{
MessageBox.Show("Authenticated", "The application has been authenticated against the server", MessageBoxButton.OK);
});
}
}
The source code here contains the code for this notification control as well as the Status Indicator control.
A lot of the built in applications have really subtle transitions and effects that really add polish to an existing application. In the process of building a new application I've been working on mimicking those controls. The first I'm releasing is the Status Indicator most commonly seen in the email application.

It's a fairly simple control that has two properties Text and InProgress controlling both the displayed status and whether the progress bar should be displayed. The control exposes two methods Display and Clear to easily set the properties of the control as well as manage state for nice animated transitions between the two.
<controls:StatusIndicator x:Name="Status" />
private void OnDisplay(object sender, RoutedEventArgs e)
{
Status.Display("Loading...", true);
}
private void OnClear(object sender, RoutedEventArgs e)
{
Status.Clear();
}
One thing that frustrates me when dealing some out of the box controls is that there's often no nice way to interact with the control when using some sort of UI separation pattern such as MVVM. To deal with this the control exposes a Source property, you can then have a property on your view model that implements the IStatusSource interface and will allow you to determine the properties and state of the control from your view model. It's all very unit testable as well!
<controls:StatusIndicator Source="{Binding Status}" />
public class StatusViewModel
{
public StatusViewModel()
{
Status = new StatusSource();
}
public IStatusSource Status
{
get; set;
}
public void Display()
{
Status.Display("Updating", true);
}
public void Finish()
{
Status.Display(String.Format("Updated {0:d}", DateTime.Now), false);
}
}
Of course here's the source code.
Almost all Windows Phone 7 applications at some point will store data on to the phone itself, the approach most developers are using is to serialize an object graph to a file which can at next use be simply deserialized.
It's a nice, easy pattern with few real problems, there's many different ways your objects can be serialized, xml, json or binary are the usual options.
To Do Today serializes the Tasks, Recurring Tasks and Categories as a single json document using the excellent Json.Net library. I was finding however that the performance of the load (deserialization) was degenerating very quickly as the amount of tasks increased, more so than I expected. After some frustrating hours tinkering with no results I jumped into the profiler and it became very apparent what my problem was.
Because To Do Today is a fairly simple application the model classes are used for serialization and exposed by the view models for display purposes. This means they inherit from PropertyChangedBase in Caliburn Micro to provide the INotifyPropertyChanged functionality.
So as each property was populated by the deserializer I was firing a property changed event. The PropertyChangedBase class in Caliburn Micro was also doing some work to dispatch that event back the UI thread since our Load was being performed asynchronously. Twenty tasks with ten properties meant two hundred events being dispatched, a performance nightmare to provide notifications to no one as there certainly wouldn't be any subscribers at that point.
There were two possible solutions to this, I could split the Task into two classes, a simple data storage Task used during the serialization process and another that implemented INPC for the view models. In a large application I would suggest doing this, but for smaller apps it seemed a little overkill.
Thankfully Caliburn Micro has support to turn off the notifications through the IsNotifiying property. So I simply hooked into the deserialization process to turn notifications off while the object is being populated. This resulted in a 75% performance increase in load times.
[OnDeserializing]
public void OnDeserializing(StreamingContext context)
{
IsNotifying = false;
}
[OnDeserialized]
public void OnDeserialized(StreamingContext context)
{
IsNotifying = true;
}
The important lessons here are, always check when you're doing notifications and dispatching events, especially when your objects are being used in different scenarios, secondly profilers are awesome for tracking this stuff down quickly.
Value converters are a really useful part of the xaml binding infrastructure, they work in Windows Phone 7, Silverlight and WPF. As we work on more and more projects in this space we build up a library of useful value converters. I'd like to illustrate some of the ones I use here.
Bitmap Image Converter
public class BitmapImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if(value is string)
return new BitmapImage(new Uri((string)value, UriKind.RelativeOrAbsolute));
if(value is Uri)
return new BitmapImage((Uri)value);
throw new NotSupportedException();
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
Boolean To Visibility Converter
public class BooleanToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if(value == null)
return Visibility.Collapsed;
var isVisible = (bool)value;
return isVisible ? Visibility.Visible : Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
var visiblity = (Visibility)value;
return visiblity == Visibility.Visible;
}
}
Colour To Brush Converter
public class ColorToBrushConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if(value == null)
return new SolidColorBrush(Color.FromArgb(0, 0, 0, 0));
if(value is Color)
return new SolidColorBrush((Color)value);
if(value is string)
return new SolidColorBrush(Parse((string)value));
throw new NotSupportedException("ColorToBurshConverter only supports converting from Color and String");
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
private static Color Parse(string color)
{
var offset = color.StartsWith("#") ? 1 : 0;
var a = Byte.Parse(color.Substring(0 + offset, 2), NumberStyles.HexNumber);
var r = Byte.Parse(color.Substring(2 + offset, 2), NumberStyles.HexNumber);
var g = Byte.Parse(color.Substring(4 + offset, 2), NumberStyles.HexNumber);
var b = Byte.Parse(color.Substring(6 + offset, 2), NumberStyles.HexNumber);
return Color.FromArgb(a, r, g, b);
}
}
Simple Type Converter
public class SimpleTypeConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return System.Convert.ChangeType(value, targetType, CultureInfo.CurrentCulture);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return System.Convert.ChangeType(value, targetType, CultureInfo.CurrentCulture);
}
}
String Format Converter
public class StringFormatConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if(parameter == null && value == null)
return String.Empty;
if(parameter == null)
return value.ToString();
return String.Format(CultureInfo.CurrentCulture, parameter.ToString(), value);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
One nice thing about value converters is because they're simple pluggable pieces of code they've easy to unit test. The unit tests for our Boolean To Visibility Converter may look like.
[TestClass]
public class BooleanToVisibilityConverterFixture
{
[TestMethod]
public void ConvertWithNullValueReturnsCollapsed()
{
var converter = new BooleanToVisibilityConverter();
var value = converter.Convert(null, typeof(Visibility), null, CultureInfo.CurrentCulture);
Assert.AreEqual(Visibility.Collapsed, value);
}
[TestMethod]
public void ConvertWithFalseReturnsCollapsed()
{
var converter = new BooleanToVisibilityConverter();
var value = converter.Convert(false, typeof(Visibility), null, CultureInfo.CurrentCulture);
Assert.AreEqual(Visibility.Collapsed, value);
}
[TestMethod]
public void ConvertWithTrueReturnsVisible()
{
var converter = new BooleanToVisibilityConverter();
var value = converter.Convert(true, typeof(Visibility), null, CultureInfo.CurrentCulture);
Assert.AreEqual(Visibility.Visible, value);
}
[TestMethod]
public void ConvertBackWithVisibleReturnsTrue()
{
var converter = new BooleanToVisibilityConverter();
var value = converter.ConvertBack(Visibility.Visible, typeof(bool), null, CultureInfo.CurrentCulture);
Assert.AreEqual(true, value);
}
[TestMethod]
public void ConvertBackWithCollapsedReturnsFalse()
{
var converter = new BooleanToVisibilityConverter();
var value = converter.ConvertBack(Visibility.Collapsed, typeof(bool), null, CultureInfo.CurrentCulture);
Assert.AreEqual(false, value);
}
I tend to create a resource dictionary named Converters.xaml to hold references to all the converters I need.
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:c="clr-namespace:CompiledExperience.Kore.Client.Converters"
mc:Ignorable="d">
<c:BitmapImageConverter x:Key="BitmapImage"/>
<c:BooleanToVisibilityConverter x:Key="BooleanToVisiblity"/>
<c:ColorToBrushConverter x:Key="ColorToBrush"/>
<c:SimpleTypeConverter x:Key="SimpleType"/>
<c:StringFormatConverter x:Key="StringFormat"/>
</ResourceDictionary>
Once that's created then you modify your Binding statements to use the Converter.
<Rectangle Fill="{Binding Colour, Converter={StaticResource ColourToBrushConverter}}" Width="12" Height="72" />
If you're using Expression Blend to wire up your bindings then you can select the Converter from the provided drop down.
The Silverlight Toolkit for Windows Phone 7 made it really useful for apps to deal with simple gestures such as tap, pinch and swipe. Wiring these gestures to event handlers is incredibly simple with the code below.
<toolkit:GestureService.GestureListener>
<toolkit:GestureListener DoubleTap="OnDoubleTap" />
</toolkit:GestureService.GestureListener>
Sometimes however we'll want to use gestures to trigger actions in Blend, this could be for simple interactivity when tapped trigger a storyboard to wiring up an Model, View, ViewModel framework such as Caliburn Micro or MVVMLight. To do this we'll need to create some Triggers.
For gestures that don't provide extra information such as Tap, Hold and Double Tap a simple trigger will work for all three, we'll provide and enumeration to let the user select what gesture they require.
public enum Gesture
{
Tap,
Hold,
DoubleTap
}
public class GestureServiceTrigger : TriggerBase<FrameworkElement>
{
public Gesture Gesture
{
get; set;
}
protected override void OnAttached()
{
var listener = GestureService.GetGestureListener(AssociatedObject);
switch(Gesture)
{
case Gesture.Tap:
listener.Tap += OnGesture;
break;
case Gesture.Hold:
listener.Hold += OnGesture;
break;
case Gesture.DoubleTap:
listener.Flick += OnGesture;
break;
}
}
protected override void OnDetaching()
{
var listener = GestureService.GetGestureListener(AssociatedObject);
switch(Gesture)
{
case Gesture.Tap:
listener.Tap -= OnGesture;
break;
case Gesture.Hold:
listener.Hold -= OnGesture;
break;
case Gesture.DoubleTap:
listener.Flick -= OnGesture;
break;
}
}
private void OnGesture(object sender, GestureEventArgs e)
{
e.Handled = true;
InvokeActions(e);
}
}

Once it's compiled you can use Blend to drag on any Action from the Assets Panel, then select the GestureTrigger for the Action.
For the Flick gesture we'll create a separate TriggerAction that also lets the user select the Using Windows Phones Gestures as Triggersdirection of the flick.
public class FlickGestureServiceTrigger : TriggerBase<FrameworkElement>
{
public Orientation Direction
{
get; set;
}
protected override void OnAttached()
{
var listener = GestureService.GetGestureListener(AssociatedObject);
listener.Flick += OnFlick;
}
protected override void OnDetaching()
{
var listener = GestureService.GetGestureListener(AssociatedObject);
listener.Flick -= OnFlick;
}
private void OnFlick(object sender, FlickGestureEventArgs e)
{
if(e.Direction != Direction)
return;
e.Handled = true;
InvokeActions(e);
}
}