Sunday, 22 May 2011

Controlling a robot arm using a Windows Phone 7 via a netduino and xbeemodules

In my latest project i'm controlling a low cost robot arm from a Windows Phone 7 custom application via a netduino and xbee modules.

Sunday, 15 May 2011

Creating a horizontal bar chart control by restyling a ListBox

In this example I have created a horizontal bar chart showing the UK election results for 2010 as a Windows Phone 7 UserControl. Like any other ListBox control in Silverlight or WPF, control is possible to bind to a class which provides its data.

The picture below shows the control deployed inside a Windows Phone application running in the emulator.



The first thing to do was to create a simple class (ElectionResults.cs) to provide the test data for the control.

ElectionResults.cs


using System;
using System.Collections.ObjectModel;

namespace HorizontalBarChartExample
{
public class ElectionResult
{
public String Party { get; set; }
public double Percentage { get; set; }
public int Votes { get; set; }
}

public class ElectionResults : ObservableCollection
{
public ElectionResults()
{
Add(new ElectionResult { Party = "Conservative", Percentage = 36.1, Votes = 10703754 });
Add(new ElectionResult { Party = "Labour", Percentage = 29.0, Votes = 8609527 });
Add(new ElectionResult{ Party="Liberal Democrat", Percentage=23.0, Votes=6836824 });
Add(new ElectionResult { Party = "Other", Percentage = 11.9, Votes = 3532874 });
}
}
}

Value Converters


The next step is to create 3  Value Converters to convert the data values to useful types which can be bound to the UI of the control.

PartyColourConverter.xaml.cs


This value converter takes the name of the political party as a string and returns its colour. If the name is not one of the main 3 parties then it simply returns 'Gray'.
using System;
using System.Globalization;
using System.Windows.Data;

namespace HorizontalBarChartExample
{
public class PartyColourConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is String)
{
var party = (String)value;
switch (party)
{
case "Labour":
return "Red";
case "Conservative":
return "Blue";
case "Liberal Democrat":
return "Orange";
default:
return "Gray";
}
}
return "";
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

PercentageConverter.xaml.cs


This ValueConverter takes the percentage of the vote as a double and simply formats it with a %. Using a value converter for this seems a little over the top but in Silverlight 3 (which is what we have on Windows Phone at the moment, you cannot apply a format within the xaml when you bind...in Silverlight 4, you can)
using System;
using System.Globalization;
using System.Windows.Data;

namespace HorizontalBarChartExample
{
public class PercentageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is double)
{
return String.Format("{0}%", value);
}
return "";
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

VotesConverter.xaml.cs


Like the percentage converter above, this simply formats the value for the view. Again, a ValueConverter will not be necessary for this in Silverlight 4.
using System;
using System.Globalization;
using System.Windows.Data;

namespace HorizontalBarChartExample
{
public class VotesConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is int)
{
return String.Format("({0:##,#})", value);
}
return "";
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

BarWidthConverter.xaml.cs


This converter takes the percentage of the vote and scales it by a constant value to provide the width of the chart bar. In this example I've just scaled by 6.5 which worked for the values but a better scaling based on the maximum percentage could easily be implemented.
using System;
using System.Globalization;
using System.Windows.Data;

namespace HorizontalBarChartExample
{
public class BarWidthConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is double)
{
double scaled = (double)value * 6.5;
return scaled.ToString();
}
return "";
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}

}
}

app.xaml


To make these value Converters available to the view they need to be included as resources. I have added them to the app.xaml file.
<Application.Resources>
<converter:PercentageConverter x:Key="PercentageConverter" />
<converter:BarWidthConverter x:Key="BarWidthConverter" />
<converter:VotesConverter x:Key="VotesConverter" />
<converter:PartyColourConverter x:Key="PartyColourConverter" />
</Application.Resources>

HorizontalBarChartExampleControl.xaml


Finally we come to the control itself. The preparation made above and the fact that we are using the MVVM pattern mean that there is very little to the control. I added a UserControl to the Windows Phone project and called it HorizontalBarChartExample.xaml.

The main grid of the control should look something like this:
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.Resources>
<src:ElectionResults x:Key="electionResults"/>
</Grid.Resources>
<ListBox ItemsSource="{StaticResource electionResults}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Party}" />
<StackPanel Orientation="Horizontal">
<Rectangle Fill="{Binding Party, Converter={StaticResource PartyColourConverter}}"
Width="{Binding Percentage, Converter={StaticResource BarWidthConverter}}" Height="30" />
<TextBlock Margin="5,0,5,0" Text="{Binding Percentage, Converter={StaticResource PercentageConverter}}" />
<TextBlock Text="{Binding Votes, Converter={StaticResource VotesConverter}}" />
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>

MainPage.xaml


All that remains is to place the control into your application page somewhere. The simplest way to do this is to drag the control into the page from the toolbox once the UserControl has been compiled. In my page it looks like this:
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>

<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock x:Name="ApplicationTitle" Text="UK Election Results" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="2010" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>

<Grid x:Name="ContentPanel" Grid.Row="1">
<my:HorizontalBarChartExampleControl Margin="25,0,0,0" />
</Grid>
</Grid>

So there we have it, a ListBox restyled to display as a horizontal bar chart.

You can download the source code here

Friday, 6 May 2011

My First #DotNetDevNet Meeting

Yesterday evening I went to my first meeting of the Bristol based .Net user group DotNetDevNet (http://www.dotnetdevnet.com/). It was an enjoyable and interesting evening starting with several small talks/demonstrations by members followed by a talk by Kendall Miller (@kendallmiller) of Gibralter Software.

The first member talk and demonstration was about ZeroMQ Socket Library which was of great interest as i'm currently working on an alerting system where this may be an option.  Good demonstration of it working on PC and Linux.

The second member demonstration was retrieving a twitter feed and displaying it on a Windows Phone. Again of great interest to me as I'm writing an app (MP Checker - more to follow about that) for the phone at the moment.

The main speaker Kendall Miller of Gibraltar Software provided a very interesting talk 'Natural Laws of Software Performance'. Kendall talked about and demonstrated ways to effectively use the increasing number of cores in todays and future multicore processors including an explanation of the limitations in processor design which will lead to more and more multiple cores.

A very interesting evening. Looking forward to next month when there will be a talk from Richard Campbell from the .Net Rocks.

Anyway...better get on with some work...this code wont write itself!