Wednesday, March 31, 2010

DMS Value Converter for Silverlight/WPF

Longitudes, latitudes and other angular measurements are normally stored as decimals degrees such as 10.25.  However angles most commonly displayed as degrees minutes and second, for example, 10°15’00”.  This post contains code for a simple application that demonstrates a decimal degrees to degrees minutes seconds value converter.  The converter is defined in code but applied in XAML for any Silverlight or WPF application.

In this example, the code is for the following WPF windows application:

DMS Value Converter

In the code behind for the window looks like this:

using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;

namespace DmsConverterSample {
    public partial class MainWindow : Window {
        public MainWindow() {
            InitializeComponent();
        }
    }

    [ValueConversion(typeof(string), typeof(string))]
    public class DmsConverter : IValueConverter {
        public object Convert(object value,
                              Type targetType,
                              object parameter,
                              CultureInfo culture) {
            // Test for Null
            if (value == null) { return "Null"; }
            string st = value.ToString();
            if (string.IsNullOrEmpty(st)) { return "Empty"; }

            // Get Angle
            double angle;
            if (!double.TryParse(st, out angle)) { return "Not an angle"; }

            // Set flag if number is negative
            bool neg = angle < 0d;

            // Work with a positive number
            angle = Math.Abs(angle);

            // Get d/m/s components
            double d = Math.Floor(angle);
            angle -= d;
            angle *= 60;
            double m = Math.Floor(angle);
            angle -= m;
            angle *= 60;
            double s = Math.Round(angle);

            // Format
            return string.Format("{0:00}°{1:00}'{2:00}\"", d, m, s);
        }
        public object ConvertBack(object value,
                                  Type targetType,
                                  object parameter,
                                  CultureInfo culture) {
            throw new NotImplementedException();
        }
    }
}

And the XAML is here:

<Window x:Class="DmsConverterSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:DmsConverterSample"
        Title="Convert from DD to DMS"
        Height="150"
        Width="400">
    <Grid Margin="5,5,5,5">
        <Grid.Resources>
            <local:DmsConverter x:Key="DmsConverter"/>
        </Grid.Resources>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="3"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <TextBlock Grid.Column="0"
                   Grid.Row="0"
                   Text="Decimal Degrees" />
        <TextBlock Grid.Column="0"
                   Grid.Row="1"
                   Text="Degrees Minutes Seconds"/>
        <TextBox x:Name="DD" Grid.Column="2" Grid.Row="0"/>
        <TextBox x:Name="DMS"
                 Grid.Column="2"
                 Grid.Row="1"
                 IsEnabled="False"
                 Text="{Binding
                    ElementName=DD,
                    Path=Text,
                    Mode=OneWay,
                    Converter={StaticResource ResourceKey=DmsConverter}}"
                 />
    </Grid>
</Window>

This samples utilises element binding.  As you type an angle in decimal degrees, the angle will automatically be converted to degrees minutes seconds in the second text box.

Thursday, March 25, 2010

Windows Phone 7 Series



Last week I attended MIX10, Microsoft’s annual web developer conference, at the Mandalay Bay in Las Vegas.  Below are a few notes I took during sessions on Microsoft’s new Windows Phones, due to hit the market during the “holidays” in 2010.
I foresee three strengths over its future nemesis, Apple’s iPhone:
  1. Windows Phone will benefit from an enormous pool of .NET-proficient developers that are skilled in Silverlight web development,
  2. Multiple hardware vendors will provide competition in the market place and also a variety of form factors,
  3. Xbox Live experience for gamers!

Hardware

  • Simplified specs to make it easier for OEMs.
  • Microsoft will write all device drives.
  • 6.6GB hard drive.
  • 250 MB RAM.
  • 8GB Flash Drive.
  • Supports up to 4 touch contacts.
  • Resolutions: 800x480 and 480x320 (later).
  • CPU: ARMv7 Cortex/Scorpion or better.
  • Three Buttons: Start/Search/Back.
  • A-GPS.
  • Compass.
  • Accelerometer.
  • Vibration.
  • GPU: Supports DirectX9.
  • Hardware Vendors: Asus, LG & Samsung.

User Experience

  • Office applications (i.e. Outlook, Excel and Word) will be bundled with Phone.
  • Uses “metro” visual style.
    • Design philosophy invented for the phone that includes, white foreground, dark background, page animations and left-to-right sliding panoramic views.
    • Inspired by transportation signs.
    • Text is truncated at sides to prompt the user to slide the screen left/right.  Microsoft uses the term “panoramic view” to describe this layout style.
    • Absence of unnecessary UI.
    • Touch targets are larger than visual elements.
  • Supports most social networking services via the Windows Live aggregator.
  • Gesture support: tap, double tap, touch and hold, flick and pinch and stretch.
  • Phone requires Windows Live authentication.

Browser

  • Does not support Flash or Silverlight web applications!  Great, no ads!

Mapping

  • The Bing Silverlight map control is bundled with the Windows Phone SDK.
    This, of course, does not exclude third party mapping controls.
  • The Windows Phone SDK will include access to free geocoding, reverse geocoding and routing services.
  • When an app requests the location of the Phone, it must specify the required accuracy (i.e. low, medium or high).  The phone will then decide the method to use to return the required accuracy.  The Phone can use wi-fi, cell phone towers, GPS or any combination.  The GPS receiver is generally less desirable due its power usage and the time required to get a fix.

Developer Experience

  • Developer tools are “free forever”.
  • Must have Microsoft Visual Studio 2010 (on Windows Vista or 7).
  • Apps are tested using a device emulator or can be published to Windows Phone (connected via USB).
  • Apps can be developed using Silverlight or XNA (both using C#).
  • Apps have access to devices (e.g. compass, accelerometer, location and camera).
  • Recommended touch target ≥9mm with ≥2mm separation between UI elements.
  • Textboxes can be assigned “input-score” such as email, telephone number, url or simply text.  Each scope will automatically launch a specific virtual keyboard.
  • Scrollviews support flick scrolling out-of-the-box.
  • Accelerometers provide force detection in three dimensions.
  • Developers have access to microphone input as a WAV stream with only 10ms latency.
  • Can only render one MediaElement at a time. That is, it is not possible to play two videos at the same time.
  • App developers have unlimited isolated storage, that is, the Silverlight “sandbox” is only limited to the size of available disk.
  • App developers are encouraged to use the page navigation (introduced in Silverlight 3) to increase performance (reduce unnecessary page reloading).
  • There is only one foreground app.
  • Background apps continue to run but with limited resources.
  • The phone may kill background apps at any time.
  • Apps are informed of foreground/background switching so they can load/save session state.
  • Only HTTP/HTTPS protocol supported.
  • SL Apps can use XNA API (except display).  For example, a SL app can use the XNA API to play music.
  • Developers have access to a user’s stored music, photos and videos.

Applications

  • Apps are developed using Visual Studio 2010, Expression Blend and XNA Studio.
  • Apps published to Windows Phone Marketplace must first be certified, checked and signed by Microsoft.
  • App framework designed for easy install and removal.  Apps cannot execute code during install/uninstall time.
  • Apps can add support for “trial software” similar to games on Xbox Live Arcade.
  • Robust security models.  The phone verifies an app is signed and certified (i.e. un-tampered) before execution.
  • Both SL and XNA apps can apply for Xbox Live certification.  This will allow gamers to receive achievements.
  • Apps do not have access to user’s Windows Live account information, only a unique device id.

Push Notifications

  • When a Windows Phone receives a notification, it is displayed as an unobtrusive toast popup.
  • When a user clicks on a toast popup, the phone will automatically start (and switch) to the associated app.
    for example, email notification, weather update, new SMS message
  • Notification infrastructure managed by Microsoft.
  • Notifications from third parties services must be sent via Microsoft’s notification server.
  • Notifications NOT guaranteed to be received (e.g. bandwidth constraints)

Silverlight Apps

  • Microsoft: Emphatically “not Silverlight light”.
  • API extended to communicate with peripherals (e.g. GPS, microphone, compass, camera, accelerometer)
  • Display is 100% hardware accelerated

XNA

  • For 2D/3D applications like games.
  • Uses looping redraw programming model.
  • Game publishers can apply for “Xbox Live” status (i.e. earn achievements)
  • Display is 100% hardware accelerated

Other

  • Phone and PC can be wireless synchronized.
  • Microsoft would not comment on support for speech-to-text or text-to-speech.
  • Microsoft will allow users to remotely lock or wipe lost/stolen phones!

Friday, March 19, 2010

How to sort an ObservableCollection

ObservableCollection<T> is frequently used in Silverlight and WPF applications as a bindable data source to elements like ListBoxes and TreeViews.  This is because the collection supports INotifyPropertyChanged, an interface that is referenced by hosts elements so they can be notified whenever the collection changes.

Unlike List<T> and other collection types, ObservableCollection<T> does not natively support sorting.  This post will explore three options for sorting an ObservableCollection.

To start, let’s define Person, a class that supports IComparable, an interface that instructs other objects how to rank person objects.

public class Person : IComparable {
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int CompareTo(object obj) {
        Person person = obj as Person;
        if (person == null) {
            throw new ArgumentException("Object is not Preson");
        }
        return this.LastName.CompareTo(person.LastName);
    }
}

Next, create a collection of Persons using ObservableCollection<Person> and populate with some well known physicists.

// Create a list of people
ObservableCollection<Person> people = new ObservableCollection<Person>();
people.Add(new Person() { FirstName = "Albert", LastName = "Einsten" });
people.Add(new Person() { FirstName = "Isaac", LastName = "Newton" });
people.Add(new Person() { FirstName = "Niels", LastName = "Bohr" });
people.Add(new Person() { FirstName = "Gottfried", LastName = "Leibniz" });
people.Add(new Person() { FirstName = "Marie", LastName = "Curry" });

The first techniques uses the OrderBy LINQ extension with a simple lambda expression.

ObservableCollection<Person> peopleSort = new ObservableCollection<Person>(
    people.OrderBy(person => person)
);

The disadvantage of this method is that a new collection is created.  Transferring items from the sorted collection to the original collection could be expensive.  The advantage however is that lambda expressions provide almost unlimited flexibility with respect to defining the sorting logic.  By default, Person objects are sorted by the LastName property as defined in its implementation of IComparable.  However to sort by FirstName we can use the following:

ObservableCollection<Person> peopleSort = new ObservableCollection<Person>(
    people.OrderBy(person => person.FirstName)
);

A second method of sorting is to make use of the existing Sort method in List<T>.

List<Person> list = new List<Person>(people);
list.Sort();

But once again, to use this method the end result is the creation of two collections.

Lastly, I would like to describe a third option for sorting ObservableCollection<T> that makes use of the custom LINQ extension as defined below.  The expression performs a bubble sort with the assumption that the items in the generic collection support IComparable.

public static class ListExtension {
    public static void BubbleSort(this IList o) {
        for (int i = o.Count - 1; i >= 0; i--) {
            for (int j = 1; j <= i; j++) {
                object o1 = o[j - 1];
                object o2 = o[j];
                if (((IComparable)o1).CompareTo(o2) > 0) {
                    o.Remove(o1);
                    o.Insert(j, o1);
                }
            }
        }
    }
}

To sort ObservableCollection<Persons> we just need the following statement.

people.BubbleSort();

In summary, I have described three methods of sorting a ObservableCollection<T>.  The first used a List<T>, the second the OrderBy LINQ extension and the last method defined a custom bubble sort LINQ extension.  Each method has its advantages and disadvantages and I am sure are more methods too.  Please feel free to comment if you would like to suggest additional methods.

Thursday, March 11, 2010

Rating Control for WPF 4.0

image

Being recently frustrated with the absence of an acceptable rating control for WPF, I ported the rating control from the Silverlight toolkit to WPF.  A link to the full source code is provided below.  To use the code you will need Microsoft Visual Studio 2010 and .NET 4.0 (currently available as a free downloadable “release candidate”).

The follow code snippet demonstrates how to use the rating control in XAML.

<Window x:Class="ESRI.PrototypeLab.Rating.Test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:rating="clr-namespace:ESRI.PrototypeLab.Rating;
assembly=ESRI.PrototypeLab.Rating"
Title="Rating control for WPF" Height="200" Width="300" > <Grid> <StackPanel Orientation="Vertical" HorizontalAlignment="Center"
VerticalAlignment="Center"> <rating:Rating x:Name="rating"
Value="{Binding ElementName=slider, Path=Value, Mode=TwoWay}"
ItemCount="5" HorizontalAlignment="Left"
Background="Transparent" Foreground="Yellow" /> <Slider x:Name="slider" Minimum="0" Maximum="1"
SmallChange="0.1" LargeChange="0.1" Value="0"/> </StackPanel> </Grid> </Window>

Click here for the source code.