Pixata Custom Controls
For Lightswitch

Recent Posts

Popular tags (# posts in brackets)

Anonymous types (3) ASP.NET (5) C# (3) C# tricks and tips (2) Computers (6) Design patterns (3) DomainDataSource (3) Dynamic data (4) Entity framework (3) Entity model framework (5) F# (3) LightSwitch (12) Linq (6) Microsoft (2) MVP (2) MVVM (2) Project Euler (2) RIA services (5) Silverlight (2) SQL Server (4) Unit testing (4) Visual Studio (7) WCF (3) WPF (3)

Gratuitous link to StackExchange

Archives


Categories


Disclaimer

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

Actually, as I'm self-employed, I guess that means that any views I expressed here aren't my own. That's confusing!


Acknowledgments

Theme modified from one by Tom Watts
C#/F# code styling by Manoli (for posts pre-2016) and Google code prettify (for post from Jan 2016 and beyond)


My rambling thoughts on exploring the .NET framework and related technologies

Why a toolbar control?

A month ago, I posted an article showing how to create a custom toolbar for a Lightswitch application. At the time, I thought that this was so easy that there was little point in creating a control extension for it. However, the more I thought about it, the more I realised that whilst it’s very easy for an experienced programmer, it wouldn’t be quite so easy for someone with less experience. Furthermore, easy as it was, it still requires you to build the toolbar yourself and write the code.

This niggled me enough to have a go at creating a control extension to implement the toolbar. Along the way I learned some new Lightswitch tricks, and ended up with a control that’s even easier to use than writing your own!

You’ll need the latest version (1.15, published today on the Visual Studio Gallery) of the control extension to follow along. Imagine we have a Lightswitch application that maintains contact details for ferrets (as you do!). We have a list and details screen that displays the ferrets’ information, and want to add a toolbar above the details side to allow the user to change the selected ferret’s name. This is a contrived example, but was the best I could think up on the spur of the moment and with little sleep! For a more realistic example of why you might want a toolbar, see my previous blog post.

Here’s a screen shot of what we’re aiming for...

A static toolbar in action

Regular readers will recognise the dear elephant that has graced this blog several times. The other icons come from my usual source, www.findicons.com, although I recently discovered some great free icons at www.proicons.com. One of the good things about that site is that the icons are organised into themes, rather than being a random collection of individual icons like www.findicons.com. Anyway, you can see that the toolbar above has five buttons, three with just an image, one with an image and text, and one with just text. The Pixata Static Toolbar control allows you to choose how your button will look (including completely restyling it if you want, see later).

Using the toolbar control

To use the control, click the “Add A Data Item” button on the Lightswitch designer window, and add a new Local Property. As with all the static controls, this is merely to get around the Lightswitch limitation of requiring all controls to be bound to something, so you can leave it as a string (uncheck the “Is Required” checkbox) and name it anything you like. I tend to call mine StaticProperty, as it helps me remember what it is when looking at the designer, but you can call it anything you like.

Drag this property onto the designer wherever you want the toolbar to appear, and change the control type to Pixata Static Toolbar control...

Choosing the Pixata Static Toolbar control

Setting the button properties

Have a look in the Properties panel. The first three properties apply to all buttons in the toolbar. The “Image width” and “Image height” properties set the size of the images to be displayed on the buttons. For simplicity (and to make the toolbar look nicer), you have to set the one width and one height, and this will be used for every button. Next you can set the margin for the button. The default is “0,0,5,0” which gives 5 pixels space to the right of each button, so they don’t squash right up next to each other. You change this to whatever you like, but the default setting is probably all you’ll ever need.

After that, you’ll see five groups of properties that look like this...

The properties for a button

Unfortunately, I don’t think there is any way to group these visually, but you’ll see that there are five sets of identical properties. The checkbox specifies if the button is displayed or not. The toolbar allows you up to five buttons, but also allows you less by clearing the checkboxes. If you want more than five buttons in a toolbar, just add two of them.

The link below the checkbox allows you to select the image that will be used for the button. The text for the button is shown next. If you just want an image on the button (like in the 1st, 3rd and 5th buttons in the screen shot at the top of this post), then leave this property blank. If you choose an image and enter text, you’ll end up with both, like the 2nd button in the screen shot earlier. If you just enter text and don’t choose an image, then you’ll end up with a text-only button, like the 4th button above. This last option isn’t that exciting, as you can do this in Lightswitch alone.

The tooltip is the text that will be displayed when your mouse hovers over the button. In the screen shot earlier, my mouse (which you can’t see) was hovering over the 2nd button, and the tooltip text is displayed.

The “Tag text” property allows you to set the tag of the button to a string. The purpose of this will be explained below.

Handling the button click event

The only other thing you need to do is to handle the event when a button is clicked. This is the only place you need to write code to use this control. Click the “Write code” button in the screen designer, and choose the ScreenName_InitializeDataWorkspace event. The first thing you need to do is add the following line at the top of the file...

using PixataCustomControls.Presentation.Controls;

Then add the following lines inside the event handler that was created for you...

partial void FerretsListDetail_InitializeDataWorkspace(List<IDataService> saveChangesTo) {
  var toolbar1 = this.FindControl("FerretToolbar");
  toolbar1.ControlAvailable += (S, E) => {
    StaticToolbar stb = ((StaticToolbar)E.Control);
    stb.ButtonClick += new System.EventHandler<StaticToolbarEventArgs>(FerretToolbar_BtnClick);
  };
}

My toolbar is called FerretToolbar, so unless you’ve chosen the same name (welcome fellow ferret fan!), you’ll need to change that to match what you chose. By default, Lightswitch will name it after your static property, but you can change this to something more meaningful.

When the ControlAvailable event fires, the code above grabs the toolbar control (which I’ve stored in a local variable called stb), and then subscribes to the ButtonClick event, which will be fired whenever someone clicks one of the toolbar buttons. To make life easier, I only added one event instead of five.

All you need now is the event handler. Here is a sample...

void FerretToolbar_BtnClick(object sender, StaticToolbarEventArgs e) {
  FerretsSet.SelectedItem.Name = e.TagText;
}

This simple example simply updates the selected ferret’s name to the tag text of the button that was clicked. If your application requires similar behaviour for each button, then using the tag text is a great way to simplify the code. This is similar to the way I inserted standard text in the previous blog post. If you don’t set the tag text, then this will set the name to the empty string.

If you want to have your buttons do distinct things, then this isn’t necessarily the best way to go, as the tag text doesn’t give enough flexibility. In this case, you can just check which button was clicked, and branch appropriately. The ButtonClick event takes a StaticToolbarEventArgs object, that contains the tag text (as shown above), as well as the number of the button. Note that the buttons are numbered one to five and NOT zero to four, as I thought that was too confusing for the general user.

Here is a sample of how to handle this case...

void FerretToolbar_BtnClick(object sender, StaticToolbarEventArgs e) {
  switch (e.ButtonNumber) {
    case 1:
      DoButtonOneStuff();
      break;
    case 2:
      DoButtonTwoStuff();
      break;
  }
}

I’ve only shown two cases here to save some space, but it would work the same if you use more buttons.

Modifying the buttons as much as you like

I know that there are people out there who will immediately ask me if they can get hold of the individual buttons, so they can customise them like crazy! Well, I’m one step ahead of you! The control exposes an indexer, which allows you to get the actual buttons on the toolbar. Once you have the toolbar itself (as I did in the FerretsListDetail_InitializeDataWorkspace event handler earlier), you can just do this...

stb[1].Content = "New Text For Button #1";

This rather pointless example shows you how to set the Content for the button to a plain string. As mentioned above, you can do this from the Properties panel without needing code, or you can use a regular Lightswitch button (generated when you drag a method onto the designer surface). However, the point here is that stb[1] is the actual button, so you can do anything to it that you could do to a normal button, including replacing the Content with something of your own invention. I can’t think of any suitably weird example, so I’ll leave that to you dear reader!

Note again that the buttons are numbered from one to five, so if you attempt to access button zero, you will get an IndexOutOfRangeException exception.

One small niggle

One thing I found was that if you want a toolbar with more than five buttons, and you use two of my static toolbar controls next to each other, Lightswitch helpfully adds three pixels of blank space between them. It does this to all controls, so they don’t get all squashed up, but in this case, it is not desirable. I contemplated hacking around to try and remove these three pixels, but decided it wasn’t worth the effort, especially as most toolbars will not have more than five buttons that need to be together. You generally find that toolbars have their buttons in smaller groups, with a vertical divider between the groups. You can do this easily by using several static toolbar controls, and separating them with the Pixata Vertical Divider control. You’ll need to add something between the divider and the next toolbar, so that Lightswitch adds its three pixels. The easiest way to do this is use a Pixata Spacer Control, with the width set to zero.. .

The 1st and 4th controls in that Columns Layout are two static toolbars. The second control is the vertical divider (width set to 1), and the 3rd control is a spacer whose width is zero.

The result of this looks like this...

I hope you find this new control useful. As usual, if you have any comments or questions, please leave them on the Visual Studio Gallery page.

Update 24th Sept ‘12

For those using VB.NET, here is a sample of an entire screen code that does pretty much the same as the code above.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Imports PixataCustomControls.Presentation.Controls

Namespace LightSwitchApplication

Public Class Customers

Private Sub Customers_InitializeDataWorkspace(saveChangesTo As System.Collections.Generic.List(Of Microsoft.LightSwitch.IDataService))
  AddHandler Me.FindControl("FerretToolbar").ControlAvailable, AddressOf FerretToolbar_ControlAvailable
End Sub

Private Sub FerretToolbar_ControlAvailable(sender As Object, e As ControlAvailableEventArgs)
  Dim FerretToolbar As StaticToolbar = TryCast(e.Control, StaticToolbar)
  AddHandler FerretToolbar.ButtonClick, AddressOf FerretToolbar_ButtonClick
  ' Set properties here if you like
End Sub

Private Sub FerretToolbar_ButtonClick(sender As Object, e As StaticToolbarEventArgs)
  Customers1.SelectedItem.Name = e.TagText
End Sub

End Class

End Namespace
Sunday, 03 June 2012 14:48:00 (GMT Daylight Time, UTC+01:00)

As my avid reader will know, I’m a huge fan of Visual Studio Lightswitch, mainly for the ease and speed with which you can get an impressive CRUD (forms over data) application up and running. However, one of the (admittedly few) limitations that I’ve found is that you don’t have as much control over the user interface (UI) as you do in WPF, Silverlight or WinForms applications. Whilst this is generally not a problem, it can sometimes be a issue.

For example, I’m currently working on an application which generates emails and documents at various times. These are based on templates that the user can modify. In order to make life easy for them, I provided an editor in the application, and wanted to give them an easy way of inserting placeholder text that would be replaced when the email or document was generated. In order to add buttons for the placeholder text items, I added several methods to the screen, and dragged these to the designer to create the buttons. As they can modify document templates and email templates, and the latter have both a subject and body, I needed three buttons for every placeholder text in use. The email tab of this screen looked like this...

The Lightswitch application before the custom toolbar

 

As you can see, I placed the two sets of buttons on the right, so they would be easily accessible when typing the template.

The problem with this is that those buttons don’t look very pretty, and they take up quite a bit of screen space. The Documents tab has another set of buttons, for inserting text into the document body. Apart from the looks, this resulted in three almost identical sets of six almost identical screen methods, with the associated problems in maintenance. This bothered me enough to wonder how hard it would be to implement a custom toolbar for Lightswitch, that could be used three times, saving me all that almost identical code.

This turned out to be almost embarrassingly easy, as I will explain with a simple example.

A Simple Example

If you want to follow along, create a new Lightswitch application, and add a table called Customers. Actually, you can add anything you like, this was just the first (moderately sensible) thing that came into my head. The table looks like this...

The Customers table in the Lightswitch designer

Now create a “List and Details Screen” based on this table. At this stage, you can run the application and add some data - don’tcha just LURVE Lightswitch!

In a desperate attempt to think of something useful here, I decided that I wanted a quick way to increase the number of orders recorded for the customer (I know, this would normally come from somewhere else in the database, but bear with me, the point here is to show you how to make a toolbar, not how to write a sensible application!) and to update the date of last contact to the current date and time.

I could do this by adding two methods to the screen, and dragging them onto the designer, but this would look as ugly as the sample I showed above. We want our users to we wowed by the fab UI we gave them, so we’re going to add... elephants! Huh? Bear with me folks, it will all become clear.

To create the toolbar, switch to File View in the Solution Explorer, and find the Client project. Add a folder named UserControls to this project, and add a Silverlight User Control named CustomerToolbar.xaml to the folder. Your Solution Explorer should look something like this...

The solution explorer in Visual Studio when you've added the user control

Aside: Strictly speaking, you don’t need to add the folder, but it’s a good idea to help keep things separate. It’s also worth noting that you don’t need to put your user control in a separate project as many people claim. Unless you’re writing something that will be reused a lot, in which case you’re better of writing an extension, there’s no need to bother with a separate project. As far as I know, the way I have shown will also work with the Express version of Visual Studio, which doesn’t allow extra projects to be added.

Now double-click the CustomerToolbar.xaml file to open it up in the Silverlight designer. There are quite a few ways of creating a toolbar, and I chose to use a set of Button controls inside a StackPanel. My XAML looked like this...

<UserControl x:Class="LightSwitchApplication.UserControls.CustomerToolbar"
             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"
             mc:Ignorable="d"
             Height="40"
             Width="130">
 
  <StackPanel Orientation="Horizontal">
    <Button Height="40"
            Width="40"
            Margin="0"
            Name="BtnElephant"
            Click="BtnElephant_Click">
      <Image Source="/CustomToolbar.Client;component/Images/elephant.png"
             Height="32"
             Width="32" />
    </Button>
    <Button Height="40"
            Width="40"
            Margin="5,0"
            Name="BtnCoffee"
            Click="BtnCoffee_Click">
      <Image Source="/CustomToolbar.Client;component/Images/rss.png"
             Height="32"
             Width="32" />
    </Button>
    <Button Height="40"
            Width="40"
            Name="BtnBell"
            Click="BtnBell_Click">
      <Image Source="/CustomToolbar.Client;component/Images/alert.png"
             Height="32"
             Width="32" />
    </Button>
  </StackPanel>
</UserControl>

I took the easy approach to adding the images, by creating empty <Image> tags, then clicking the Source property in the Properties panel, clicking the Add button and navigating my way to the PNG file I was using. Visual Studio added the image to my project and set the Build Action to Resource for me. You can do this manually, but why bother?

The designer now looked like this...

The toolbar control in the Visual Studio designer

 

As you can see, we have an elephant, a coffee cup and a bell. All the icons came from www.findicons.com, my usual favourite source of free icons. I picked these three more for their looks than their significance to the task at hand. In a real application, you would want to pick something more meaningful. I also didn’t add tool tips in the XAML above. These are a good idea, and will be added in the final version shown later.

Now switch the Solution Explorer back to Logical View, and double-click the Customers screen you created earlier. We want to add the toolbar to our screen, but as you probably know, version 1 of Lightswitch only allows you to add data-bound items to a screen. We get around this by adding a Local Property to the screen. Click the “Add Data Item…” button at the top of the window, then choose “Local Property,” uncheck the “Is Required” checkbox and give it a name. I tend to use StaticProperty, as this helps me remember what it is, but you can call it anything you like.

Now drag the property onto your screen wherever you want the toolbar to appear. In my case, the screen is a “List and Details” screen, and I want the toolbar above the details section. Once it’s on the screen, change the control type to Custom Control, and in the Properties panel, click the “Change” link. From the window that appears, choose the control...

The window where you can pick the custom control

My screen designer now looked like this...

The Lightswitch screen designer when the custom control has been added

If you run the application now, you’ll see the toolbar looking very smart...

The toolbar on the Lightswitch application

Looks very nice, but it doesn’t to anything yet. We’ll fix that right now.

In order to have the toolbar notify the Lightswitch screen when someone clicks a button, we’ll add some event handlers to the code. Switch to the code-behind file for the control, which in my case is called CustomerToolbar.xaml.cs (you’ll need to be in File View to see this), and change the code to look like this...

using System;
using System.Windows;
using System.Windows.Controls;
 
namespace LightSwitchApplication.UserControls {
  public partial class CustomerToolbar : UserControl {
    public CustomerToolbar() {
      InitializeComponent();
    }
 
    public event EventHandler Elephant;
 
    private void BtnElephant_Click(object sender, RoutedEventArgs e) {
      EventHandler eh = Elephant;
      if (eh != null) {
        eh(this, null);
      }
    }
 
    public event EventHandler Coffee;
 
    private void BtnCoffee_Click(object sender, RoutedEventArgs e) {
      EventHandler eh = Coffee;
      if (eh != null) {
        eh(this, null);
      }
    }
 
    public event EventHandler Bell;
 
    private void BtnBell_Click(object sender, RoutedEventArgs e) {
      EventHandler eh = Bell;
      if (eh != null) {
        eh(this, null);
      }
    }
  }
}

In this case, I’ve added three separate event handlers, one for each button. This is fine if each button does something quite different. In the case of my original application, all the buttons are to do a very similar task, so we can make the code easier, as I’ll show soon. Also, you would probably want to refactor this code to make it slimmer, as there is a lot of almost identical code here. I didn’t bother for this simple example, but will show how this could be done later.

Back in the Lightswitch screen code behind, we simply need to catch the toolbar’s events, and then do whatever we want in response. For the purposes of this demo, I’m going to have the elephant button increase the number of orders for the current customer, and the coffee button set the date last contacted to the current date/time. Here is the complete screen code...

using System;
using System.Collections.Generic;
using LightSwitchApplication.UserControls;
using Microsoft.LightSwitch;
using Microsoft.LightSwitch.Presentation.Extensions;
 
namespace LightSwitchApplication {
  public partial class CustomersScreen {
    partial void CustomersScreen_InitializeDataWorkspace(List<IDataService> saveChangesTo) {
      this.FindControl("Toolbar").ControlAvailable += (S, E) => {
        ((CustomerToolbar)E.Control).Elephant += new EventHandler(CustomersScreen_Elephant);
        ((CustomerToolbar)E.Control).Coffee += new EventHandler(CustomersScreen_Coffee);
        ((CustomerToolbar)E.Control).Bell += new EventHandler(CustomersScreen_Bell);
      };
    }
 
    void CustomersScreen_Elephant(object sender, EventArgs e) {
      if (CustomersSet.SelectedItem != null) {
        CustomersSet.SelectedItem.NumberOfOrders++;
      }
    }
 
    void CustomersScreen_Coffee(object sender, EventArgs e) {
      if (CustomersSet.SelectedItem != null) {
        CustomersSet.SelectedItem.DateOfLastContact = DateTime.Now;
      }
    }
 
    void CustomersScreen_Bell(object sender, EventArgs e) {
    }
  }
}

As you can see, in the InitializeDataWorkspace event, we grab the toolbar control and set up handlers for the three events. In the event handlers themselves, we set the customer’s properties. I haven’t done anything in the third event handler here, mainly because I couldn’t think of anything useful, given the limited scope of this simple example!

If you run the application now, you’ll find that the elephant and coffee cup buttons work as expected (assuming you expect an elephant to increase the number of orders, and a coffee cup to set today’s date of course!). We have a fully working toolbar, with amazingly little effort.

In this sample, I have added a separate event handler for each button, which is fine when the buttons do quite distinct tasks, as these do. In the original application I showed at the top, the buttons all do a very similar job, so we can improve this control quite a lot...

Tidying Up The Toolbar Code

As I mentioned above, my original case was where I wanted the buttons to insert standard bits of text into controls on the screen. As each button on the toolbar is to do basically the same job, with only a variation in the actual text, we can set up one event in the toolbar control, and use an EventArgs class to pass the text back to the Lightswitch screen.

Imagine the requirements for our sample app have changed, and we now want to set the Customer Name to one of three specified bits of text, depending on which button is pressed.

Switch to File View again, and in the same folder where you created the user control, add a class called CustomerToolbarEventArgs, whose code should look like this...

using System;
 
namespace LightSwitchApplication.UserControls {
  public class CustomerToolbarEventArgs : EventArgs {
    public string Text { get; set; }
  }
}

This class adds a single string property to the standard EventArgs class, which we’ll use to pass the text to be inserted back to the Lightswitch screen.

Change the toolbar control’s code to look like this...

using System;
using System.Windows;
using System.Windows.Controls;
 
namespace LightSwitchApplication.UserControls {
  public partial class CustomerToolbar : UserControl {
    public CustomerToolbar() {
      InitializeComponent();
    }
 
    public event EventHandler<CustomerToolbarEventArgs> BtnClick;
 
    private void FireEvent(string Text) {
      CustomerToolbarEventArgs Ev = new CustomerToolbarEventArgs {
        Text = Text
      };
      EventHandler<CustomerToolbarEventArgs> eh = BtnClick;
      if (eh != null) {
        eh(this, Ev);
      }
    }
 
    private void BtnElephant_Click(object sender, RoutedEventArgs e) {
      FireEvent("I like buns!");
    }
 
    private void BtnCoffee_Click(object sender, RoutedEventArgs e) {
      FireEvent("No sugar please!");
    }
 
    private void BtnBell_Click(object sender, RoutedEventArgs e) {
      FireEvent("Ding dong!");
    }
  }
}

As you can see, we now only have one event handler, which is generic to the CustomerToolbarEventArgs that we created above. The Click event handlers for the three buttons call a common method that sets up an instance of this class, and raises the event.

Now, we can simplify the Lightswitch screen by changing the code to this...

using System;
using System.Collections.Generic;
using LightSwitchApplication.UserControls;
using Microsoft.LightSwitch;
using Microsoft.LightSwitch.Presentation.Extensions;
 
namespace LightSwitchApplication {
  public partial class CustomersScreen {
    partial void CustomersScreen_InitializeDataWorkspace(List<IDataService> saveChangesTo) {
      this.FindControl("Toolbar").ControlAvailable += (S, E) => {
        ((CustomerToolbar)E.Control).BtnClick += new EventHandler<CustomerToolbarEventArgs>(CustomersScreen_ToolbarButtonClick);
      };
    }
 
    void CustomersScreen_ToolbarButtonClick(object sender, CustomerToolbarEventArgs e) {
      if (CustomersSet.SelectedItem != null) {
        CustomersSet.SelectedItem.CompanyName = e.Text;
      }
    }
  }
}

We only handle the one toolbar event, and just pull the required text from the CustomerToolbarEventArgs.

If you run this now, you’ll find that all three buttons modify the customer name property as expected.

After implementing this idea in my original application, the UI was much neater, as you can see from the screen shot below, and I had reduced the amount of code significantly. More to the point, maintenance was now pretty easy, as I had removed all the duplication.

My original Lightswitch application with the new toolbars in place

Obviously, there is a lot more that can be done here. The more I think about this, the more I realise that it opens up the possibilities of providing a custom UI for a Lightswitch application very easily, without requiring you to write a custom shell. Once again we see how Lightswitch gives you enormous leverage right out of the box, without sacrificing the flexibility that you need.

Thursday, 03 May 2012 11:05:00 (GMT Daylight Time, UTC+01:00)

In yesterday’s blog post, I introduced the Toast control that was added to the Pixata Custom Controls extension for Lightswitch. I mentioned at the end of the post that there were ways of creating much more flexible toasts. In this post, I’ll show you an example of what I meant. With only a little imagination, you should be able to tweak this little toasties to do almost anything!

The limitation with the method I showed yesterday is that it only allows you to set the title and message for the toast, and each of these has to be sent as plain text, without any formatting. In many cases, this is fine, but sometimes you want more control. The important thing to remember is that when you create your own toast, there is nothing to stop you from doing what you like with it before passing it to the ShowToast method. You can create a toast with any properties you like, populate those in your Lightswitch screen’s code-behind, and when you are done, pass it in to ShowToast. You are not limited to passing “new MyToast()” like I showed yesterday.

As an example, I’m going to assume you want to show a pop-up with some RSS feed information in it. I realise that this isn’t very likely from Lightswitch, but it was the first thing that sprang into my mind, partly inspired by finding a nice RSS icon on www.findicons.com. I called the new toast control ToastWithPeanutButter, mainly because I have a very childish sense of humour!

Create the basic control by following the instructions I showed yesterday.

Now, instead of restricting ourselves to two TextBlock controls for the title and message, we are going to do something a little more interesting for the message. Open up the ToastWithPeanutButter.xaml file, and replace the content with the following...

<uc:PixataToastControlBase x:Class="LightSwitchApplication.ToastWithPeanutButter"
                           xmlns:uc="clr-namespace:PixataCustomControls.Presentation.Controls;assembly=PixataCustomControls.Client"
                           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"
                           mc:Ignorable="d"
                           d:DesignHeight="100"
                           d:DesignWidth="400">
 
  <Grid x:Name="LayoutRoot">
    <Grid.RowDefinitions>
      <RowDefinition Height="Auto" />
      <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <!-- Title bar -->
    <Grid HorizontalAlignment="Stretch"
          VerticalAlignment="Stretch">
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="Auto" />
      </Grid.ColumnDefinitions>
      <Grid.Background>
        <LinearGradientBrush EndPoint="0.5,1"
                             StartPoint="0.5,0">
          <GradientStop Color="#FFE3EFF7"
                        Offset="0" />
          <GradientStop Color="#FFD6E7F3"
                        Offset="1" />
        </LinearGradientBrush>
      </Grid.Background>
      <TextBlock Name="TitleTb"
                 HorizontalAlignment="Center"
                 Text="Title"
                 FontWeight="Bold" />
      <Button VerticalAlignment="Center"
              HorizontalAlignment="Right"
              Grid.Column="1"
              Margin="5,3"
              Width="14"
              Height="14"
              Padding="0"
              Click="Button_Click">
        <Button.Content>
          <Image Source="/TestingPixataWithFerrets.Client;component/Images/closebutton.png"
                 Width="14"
                 Height="14"
                 HorizontalAlignment="Center"
                 VerticalAlignment="Center" />
        </Button.Content>
      </Button>
    </Grid>
    <!-- Main content area -->
    <Grid Grid.Row="1">
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="*" />
      </Grid.ColumnDefinitions>
      <!-- tea cup RSS icon -->
      <Image Width="64"
             Height="64"
             Margin="8"
             VerticalAlignment="Center"
             HorizontalAlignment="Center"
             Source="/TestingPixataWithFerrets.Client;component/Images/rss.png" />
      <TextBlock Name="MainContentTb"
                 Grid.Column="1"
                 Margin="3"
                 Text="Main content" />
    </Grid>
    <Grid.Background>
      <LinearGradientBrush EndPoint="0.5,1"
                           StartPoint="0.5,0">
        <GradientStop Color="#FFFF9B00"
                      Offset="0" />
        <GradientStop Color="#FFF8D183"
                      Offset="1" />
      </LinearGradientBrush>
    </Grid.Background>
  </Grid>
</uc:PixataToastControlBase>

If you look at this in the Visual Studio designer, it will look like this...

The new toast in the VS designer

Looks pretty much like the previous ones eh? It is, but we are going to do one thing differently, and that will make a lot of difference.

Switch to the code behind, and override the TitleText property as before, as we are using a plain string for the title. However, instead of overriding the MessageText property, we are going to expose the MainContent TextBlock control, so that the calling code can manipulate it. Change the code to look like this...

using System.Windows;
using System.Windows.Controls;
using PixataCustomControls.Presentation.Controls;
 
namespace LightSwitchApplication {
  public partial class ToastWithPeanutButter : PixataToastControlBase {
    public ToastWithPeanutButter() {
      InitializeComponent();
    }
 
    public override string TitleText {
      set {
        TitleTb.Text = value;
      }
    }
 
    public TextBlock MainContent {
      get {
        return MainContentTb;
      }
    }
 
    private void Button_Click(object sender, RoutedEventArgs e) {
      CloseMe();
    }
  }
}

Notice that we don’t override the MessageText property, so anything we pass in for that parameter will not be used.

Our new toast is complete, let’s see how we can use it. In a Lightswitch screen code-behind, add the following...

Dispatchers.Main.BeginInvoke(() => {
  ToastWithPeanutButter toast = new ToastWithPeanutButter();
  TextBlock tb = toast.MainContent;
  tb.Text = "";
  tb.Inlines.Add(CreateRun("DotNetWhatNot - ", Bold: true));
  tb.Inlines.Add(CreateRun("7th Mar '12 16:42"));
  tb.Inlines.Add(new LineBreak());
  tb.Inlines.Add(CreateRun("Toast control added to Pixata Custom Controls for Lightswitch", ForeGround: Colors.Brown));
  tb.Inlines.Add(new LineBreak());
  tb.Inlines.Add(CreateRun("Some MSDN Blog - ", Bold: true));
  tb.Inlines.Add(CreateRun("7th Mar '12 17:31"));
  tb.Inlines.Add(new LineBreak());
  tb.Inlines.Add(CreateRun("Microsoft announce new version of VS - no Lightswitch!!", ForeGround: Colors.Brown));
  PixataToastHelper.ShowToast("Latest RSS feeds", "", toast, Width: 400, Height: 100);
});

For convenience, this uses the following utility method...

private Run CreateRun(string Text, int FontSize = 11, Color? ForeGround = null, bool Bold = false) {
  Run r = new Run {
    Text = Text,
    FontSize = FontSize,
    Foreground = (ForeGround == null ? new SolidColorBrush(Colors.Black) : new SolidColorBrush((Color)ForeGround)),
    FontWeight = (Bold ? FontWeights.Bold : FontWeights.Normal)
  };
  return r;
}

This utilises a little-known feature of the TextBlock control, that you can add formatted multiline text to it by manipulating the Inlines collection, which can take Run and LineBreak objects. Using this utility method, we build up a list of two RSS items, which in reality would be pulled from your data source. I hard-coded the information to keep the example simple.

The result of this is the following toast..

The new toast

That’s a definite improvement over yesterday’s toast!

Obviously, you don’t need to do all that work creating Run and LineBreak objects if you don’t want, you can just add more controls to the toast’s XAML, and expose their Text (or other) properties from the toast control. That way, the code you write in Lightswitch can set up the toast as you want before passing it to the ShowToast method.

I hope this post has whetted your appetite for creating more interesting toasts. If you have a toast that you feel would be useful to others, or just want to share an interesting creation, please let me know.

Wednesday, 07 March 2012 17:54:00 (GMT Standard Time, UTC+00:00)

I have just updated my Pixata Custom Controls extension for Lightswitch. Version 1.10 contains what I believe is the very first notification toast implementation for Lightswitch. As its usage differs from other controls, and it allows significantly more customisation than the others, I decided to write a blog post about it.

The simple usage of the control is to allow you to display a small notification window in the lower right-hand corner of the user’s screen (upper right-hand if they are using a Mac), which will not interfere with whatever they are doing, and will quietly go away after a short time. They are officially called “notification windows” but are colloquially known as toast, due to the way they pop up. One of the most famous uses of toast is when Microsoft Outlook informs you that you have a new email. This is a very user-friendly way of doing this, and is far better than the evil message boxes that plagued user interfaces for decades. If you still things message boxes are OK, please read some more about why they are evil and stop using them!

Imagine you were writing an application that maintained a list of ferrets (well, don’t we all?), and you wanted to notify the user when a new ferret had been added to the database. Instead of annoying them with a message box, you could simply pop up a notification like this...

A notification toast

The user can either ignore it, or click the close button to dismiss it.

I thought it would be really nice if we could have these in Lightswitch, and devoted the whole of today to developing a control to do just that.

Before I continue though, it’s worth pointing out that due to a limitation in the Silverlight API, toasts will only work in Out-Of-Browser applications. If you attempt to use this control in a browser, nothing will happen. Also, according to the documentation, you can’t have any interactive controls on the toast, although it was quite easy to add the close button (look at the top-right of the toast in the picture above), so I’m not sure that this is as restrictive as it sounds. Finally, the API does not give any control of the fade in/out duration, the shape of the toast (so no rounded corners), or the way the toast appears (eg sliding in as opposed to fading in), so we are stuck with the default behaviours in these respects. Having said that, there’s still a lot you can do with them, as I hope to show. With that aside, let’s see how to use the control.

Displaying Toast

If you have the latest version of the Pixata Custom Controls extension for Lightswitch, then all you need to do to display toasts is to switch to the code behind of the screen where you want the notification to appear. At the top of the file, add the following line...

using PixataCustomControls.Presentation.Controls;

You don’t need to worry about adding a reference to the controls, if you’ve enabled them in the Lightswitch project properties, then the reference will already be there.

To display the toast, you can do something as simple as this...

  PixataToastHelper.ShowToast("Title", "Type your message here");

This will display a fairly plain toast, using the title and message you supplied. Obviously, you can modify these to suit your needs, including data from the Lightswitch application.

If you want something a little more interesting, you can customise the toast by adding the following parameters to the call to ShowToast...

Parameter Meaning
ToastStyle There is an enumeration in the control that gives you five more styles for the toast. These are Info, Warning, Alert, Error and Elephant. The more observant readers may notice that the last one is a little out of place. This is because I was creating a custom style to show how easy it is to add your own (see below), and decided to leave it in as it amused me.

If you change the call to the following, you’ll end up with a toast that looks like the one shown above...

  PixataToastHelper.ShowToast("Ferret Information", "New ferret added 6th March '12, by user Freddy",
    PixataToastHelper.PixataToastStyles.Info);
Notice that last parameter? That sets one of the six predefined styles (including the default Plain style), and will be suitable for most purposes.
TimeOut This integer value specifies for how milliseconds the toast will be displayed before it disappears.

Due to limitations in the .NET API, this value cannot be less than zero (I believe Microsoft are working on time travel, but I don’t think it will be available until .NET 5 comes out), nor greater than 30000. Any values outside of this range will be modified to be between zero and 30000.
Width and Height These are pretty self-explanatory. Again, due to API limitations, toasts cannot be wider than 400 pixels, nor higher than 100 pixels. If you enter a value less than zero or greater than these maximum values, it will be modified.

That’s basically all there is to the standard usage. As you can see, very easy to use, but very effective.

However, you might look at these and say “I don’t like your designs, I want it different.” Well, that’s absolutely fine, because I added the capability for you to create your own toast styles! It’s a little more involved than the standard usage, but not much.

Creating Your Own Toast

The first thing you’ll need to do is to add a new Silverlight User Control to your Client project. For the purposes of this blog post, I’m going to show you how I built the Elephant style. Truth is, the only reason that style ended up in the extension is because once I had built it, I liked it enough to keep it! So, imagine you have called your control MyToast, although why you would do that is beyond me. I have no idea why Microsoft think that we all want our folders called My Documents, and My Viruses and so on. Anyway, I had a senior moment and called my sample control MyToast, so you’re going to have to live with that for this tutorial.

You will need to make a few changes to the control before you start designing your toast. Without boring you with the details, any toast control needs to be derived from a base control I wrote for the purpose. This allows you to pass the toast into the ShowToast method. At the top of the XAML, add a reference to the Pixata Custom Controls namespace, and then change the top-level tag from UserControl to uc:PixataToastControlBase as follows...

<uc:PixataToastControlBase x:Class="LightSwitchApplication.MyToast"
  xmlns:uc="clr-namespace:PixataCustomControls.Presentation.Controls;assembly=PixataCustomControls.Client"

I also like to add a design width and height, as these make it easier to work with when you’re designing the toast. The end of your opening tag should look like this...

  mc:Ignorable="d"
  d:DesignHeight="100"
  d:DesignWidth="400">

Now switch to the control’s code behind, and have the control inherit from PixataToastControlBase instead of UserControl. You’ll need to add the following using at the top of the file...

using PixataCustomControls.Presentation.Controls;

...and then change the class declaration as follows...

  public partial class MyToast : PixataToastControlBase {

At this stage, you can now happily design your toast. If you want to play along, here is the XAML for my elephant control...

<uc:PixataToastControlBase x:Class="LightSwitchApplication.MyToast"
                           xmlns:uc="clr-namespace:PixataCustomControls.Presentation.Controls;assembly=PixataCustomControls.Client"
                           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"
                           mc:Ignorable="d"
                           d:DesignHeight="100"
                           d:DesignWidth="400">
 
  <Grid>
    <Grid.ColumnDefinitions>
      <ColumnDefinition Width="*" />
      <ColumnDefinition Width="100" />
    </Grid.ColumnDefinitions>
    <StackPanel Orientation="Vertical"
                Background="Black">
      <TextBlock Name="Title"
                 Text="The Title"
                 Margin="2,0"
                 HorizontalAlignment="Center"
                 FontWeight="Bold"
                 FontSize="14"
                 Foreground="White" />
      <Rectangle HorizontalAlignment="Stretch"
                 VerticalAlignment="Top"
                 Margin="5,0"
                 Fill="#FFC4C4C4"
                 Height="1" />
      <TextBlock Name="Message"
                 Text="The stuff on the toast that blathers on about nothing"
                 Margin="5,0"
                 VerticalAlignment="Top"
                 HorizontalAlignment="Left"
                 Foreground="White"
                 TextWrapping="Wrap" />
    </StackPanel>
    <Button Grid.Column="1"
            Padding="0"
            Click="Button_Click">
      <Button.Content>
        <Image Width="100"
               Height="100"
               Source="/TestingPixataWithFerrets.Client;component/Images/elephant100x100.png" />
      </Button.Content>
    </Button>
  </Grid>
</uc:PixataToastControlBase>

Obviously, you don’t have to add a picture of an elephant, but it won’t look as nice if you don’t! I found this one from www.findicons.com. Here’s how it looked in the Visual Studio designer...

The elephant toast in the VS designer

Notice that I’ve included a button in the XAML, and wired up the Click event. This allows the user to dismiss the toast before it times out. In this instance, the button is disguised as an elephant, which isn’t actually very user friendly. The Elephant toast style that comes with the control has a normal close button in the top right-hand corner of the toast, which is generally a better idea. People just aren’t used to the idea of clicking elephants yet!

Now, in order to get the title and message into your controls, you can override two string properties from the base class (actually from an interface that the base class implements, but let’s not split hairs)...

    public override string TitleText {
      set {
        Title.Text = value;
      }
    }
 
    public override string MessageText {
      set {
        Message.Text = value;
      }
    }

In this case, Title and Message are the names of the two TextBlock controls I put in the XAML. If you name yours differently, just modify this code.

The only other thing left to do is add a handler for the button’s Click event, which is used to allow the user to close the toast. Put the following code right below the two properties...

    private void Button_Click(object sender, RoutedEventArgs e) {
      CloseMe();
    }

CloseMe is a method in the base toast class that you inherited earlier, so you don’t need to write any more code than this.

Using The Toast In Lightswitch

Now you are ready to test your control. In your Lightswitch screen’s code behind, use the second overload of the ShowToast method, that takes your new toast control instead of a value from the enumeration. Note that as you are creating a control, you need to dispatch to the main thread, to avoid access violation exceptions. When using the built-in toast styles, you don’t need to worry about this as the control does it for you...

  Dispatchers.Main.BeginInvoke(() => {
    PixataToastHelper.ShowToast("Elephants!", "Watch out for the elephants!", new MyToast(), Width: 200, Height: 100);
  });

I have overridden the default width and height values here, and the result looks like this...

A notification toast

If you leave it alone, the toast will disappear after 4 seconds (as we didn’t override the default), or you can click the elephant and the toast will disappear immediately.

As mentioned above, it would be more intuitive to have the button look like a button, but I’ll leave that for you as an exercise. A slightly modified version of the elephant ended up in the extension.

As it stands, the control allows the display of a title and message. You can omit either of these if you wish, you just don’t override the appropriate property in your toast control’s code behind. Also, for those who find these two properties too limiting, there are ways of creating much richer, more flexible toast controls, but as this post is quite long already, I’ll leave that for another day.

I hope this is all clear, and you find the control useful. Please feel free to leave comments below.

Update 7th Mar: I have posted the follow-up article showing how to produce more advanced toasts.

Tuesday, 06 March 2012 19:25:00 (GMT Standard Time, UTC+00:00)

I was recently involved in a discussion on the Lightswitch forum, in which someone asked about updating the data in the view model before the current control lost focus. He was using a modal window that had only one text box on it, and wanted to set the enabled status of the OK button, depending on what was in the text box. The problem he had was that the ABCCanExecute method only fired when the text box lost focus, which couldn’t happen as there weren’t any other (enabled) controls on the window. I suggested an answer, which led me to remember a similar issue I had contemplated some time ago...

As part of my Pixata Custom Controls For Lightswitch extension, I wrote a control that displays a clickable web link. You can see the control to the right of the text box holding the web address in the screen shot below. If you click on the link, it would open the web page in your default browser.

The web link control on a Lightswitch screen

An issue I had with this was that when I changed the text in the text box, the clickable link would only be updated when the text box lost focus. I wanted the link to change as I typed.

I had a play with this today, and realised that whilst the answer is pretty simple, it might be worth blogging about it.

The way to get around this is to capture the TextChanged event of the text box, and manually update the view model data. The steps to do this are as follows:

1) In the InitializeWorkspace method of the screen, grab the text box (or strictly speaking, grab a proxy for it), and subscribe to the ControlAvailable event. This means that when Lightswitch paints the control on the screen (which might not always be as the screen is first displayed), you have access to the text box.

2) Save the text box in a private variable, so you can get at it later if you need to. This step isn’t strictly necessary, but I often do it as it comes in useful.

3) Subscribe to the text box’s TextChanged event, and in the handler, grab the updated text.

Here is some code that shows it in action...

   1:    partial void FerretsDetail_InitializeDataWorkspace(List<IDataService> saveChangesTo) {
   2:      var WebTextBox = this.FindControl("WebTextBox");
   3:      WebTextBox.ControlAvailable += new EventHandler<ControlAvailableEventArgs>(WebTextBox_ControlAvailable);
   4:    }
   5:   
   6:    private TextBox webTextBox;
   7:    void WebTextBox_ControlAvailable(object sender, ControlAvailableEventArgs e) {
   8:      webTextBox = (TextBox)e.Control;
   9:      webTextBox.TextChanged += new TextChangedEventHandler(webTextBox_TextChanged);
  10:    }
  11:   
  12:    void webTextBox_TextChanged(object sender, TextChangedEventArgs e) {
  13:      Ferrets.Web = webTextBox.Text;
  14:    }
  15:  }

On line 2, we get hold of the IContentItemProxy, which is basically something that stands in for the control until it is available. On line 3, we subscribe to the ControlAvailable event, which is on lines 7-10. Line 6 contains the declaration for the variable that will store the text box in case you need it later. On line 8, we pull the text box itself out of the event args that were passed in, and on line 9 we subscribe to the TextChanged event. Line 13 simply grabs the text form the text box, and pushes it into the Web property of the screen’s query (which in this case is called Ferrets).

The end result of this is that as you type in the web text box, the link text (and underlying address) is changed in real time.

This technique can be extended to do all sorts of clever things, removing some of the natural limitations of working in a Lightswitch screen.

Monday, 05 March 2012 14:45:00 (GMT Standard Time, UTC+00:00)
# Tuesday, 06 December 2011

"I have always wished for my computer to be as easy to use as my telephone; my wish has come true because I can no longer figure out how to use my telephone."

Danish computer scientist Bjarne Stroustrup

Tuesday, 06 December 2011 14:00:00 (GMT Standard Time, UTC+00:00)

A problem with anonymous types

One of my first posts on this blog was about the problem of using anonymous types when you want to send the data outside of your current class. At the time, the only way I knew to solve this was to create a simple class that had the structure of the anonymous type, and create one of these instead of the anonymous type. I do this regularly, although I have taken to naming such classes CustomerOverview, OrderOverview, etc, instead of CustomerTmp as I did in that blog post, as they aren't really temporary classes at all, they are slim, flattened overviews of the class.

This approach works well, but it can have its downsides. One, as mentioned in that post, is that it is easy to end up with a proliferation of classes, many of which may only be used in one location in the code. If the classes represent lightweight views of entities in the model (such as the two examples shown above), then I don't worry about this, as it is clear what they represent, and it's fairly certain that I'll end up using them somewhere else at some point.

However, the problem does become more apparent when the classes are very specific to one part of the code. I feel uncomfortable having classes that don't really represent anything in the object model as a whole. Granted, this isn't a very common scenario, as if your code is structured sensibly, you will probably find that you don't have these artificial classes, but it is something that happens every now and then.

For some odd reason, I was struck with an idea whilst I was washing my face the other morning! Now why this would pop into my head at 6am, when I hadn't even thought about the issue for a year or so is beyond me, but I don't claim to understand the workings of the human mind, especially one that is bleary from lack of sleep!

A little-known, but intriguing class

One of the less-known and more interesting (but ultimately useless in my experience) additions to the .NET framework version 4 was the Tuple class. This generic class allows you to create an object that consists of up to eight pieces of information of a specified type (Note: the slightly arbitrary reason why they picked eight as the maximum can be found in this MSDN Magazine article).

As an example, suppose you want to get a list of customer names and database IDs, but don't need any of the other information in your customer entity. Instead of creating a CustomerOverview class, you could just create a Tuple<int, string> which would hold the two pieces of information. Thus, you may have a method with a signature like...

  public List<Tuple<int, string>> GetCustomerIdAndNames() {
    List<Tuple<int, string>> customers = new List<Tuple<int, string>>();
    // In reality, this would be populated from a database...
    customers.Add(new Tuple<int, string>(1, "Fred"));
    // etc...
    return customers;
  }

So far so good. All of this looks jolly useful eh? So why did I describe it as ultimately useless? Only because my few experiences with using the Tuple class have ended up with changes in the requirements, which meant that every bit of code that used the Tuple had to be changed, at which point it became clear that it would have been much better design to have used a WhateverOverview class in the first place. So, whilst it's an interesting addition to the framework, it's one that I have never actually used (for very long anyway).

All that changed at 6am the other day. I had a flash of inspiration, which can be quite unnerving at that time of the morning!

Binding ASP.NET Repeaters to collections of Tuples

The issue I had that prompted that old blog post was sending data to an ASP.NET page, where it would be rendered using a Repeater control. For those of you not familiar with ASP.NET, this server-side control allows you to display a collection of items on a web page, without having to write all the code to loop through the collection and render it yourself. You just set up a simple template, bind the collection to the control, and the ASP.NET rendering engine does it for you. Now, those masochists who like writing everything themselves (such as those who use ASP.NET MVC!) might turn their noses up at such ideas, but as a professional ASP.NET developer for many years, I rely on controls like this to help me work more quickly. Microsoft provide a robust and efficient way of doing a job, why should I ignore it and do the whole thing by hand?

Anyway, the problem comes when you want to pass a collection of anonymous types to a Repeater. As the rendering engine needs to know the of each item in type of the collection, so that it can handle it appropriately, you can't bind a collection of anonymous types to a Repeater. So, to continue my earlier example, if you want to use just the customer ID and name in the Repeater, you either have to send across the whole Customer entity (which may involve a large amount of unneeded data), or create a CustomerOverview class, and pass a collection of those.

In this case, a customer is a logical enough entity that you might want to create the CustomerOverview, but there are many cases where you wouldn't. The specific collection of data items you want may be unique to this view, and creating a custom class for it would pollute the overall object model.

The simple answer to the problem is to generate a collection of Tuples, and pass that to the Repeater. As the Tuple is a known class, and the instance of it is strongly-typed, the ASP.NET engine won't have any problem with it at all, and can happily render the data without the need for an overview class.

A fairly simple answer, using a class that turned out not to be so useless after all!

A caveat

I would be remiss if I didn't end off with a comment about this approach. Although it works, and neatly solves the problem, I have to say that I'm still not a huge fan of using Tuples, especially when they are going to be passed outside of the class in which they are created. The reason is simply as I stated above, that requirements change, and if you find the need to change the length of the Tuple, or change the type of one of the items, you end up having to modify code in multiple classes. This gives the very strong feeling that you're working with strongly-coupled code, which is never a good idea.

Having said that, many times when you pass a collection to a Repeater, you don't actually need any code in the ASP.NET code-behind, as most of the data binding can be done automatically, so you probably don't need any code in the code-behind that is specific to the Tuple in question. Therefore, if you change the Tuple where it is generated, you won't need to change anything in the ASP.NET for it to continue working. This is especially true if you are using MVP, where the presenter can take care of any formatting that you want on the data items. In a case like this, I would be happy to use Tuples.

Phew, that was quite a lot of thought for first thing in the morning!

Friday, 04 November 2011 12:09:00 (GMT Standard Time, UTC+00:00)

I previously blogged about a seemingly innocent LINQ problem that had us baffled for ages, which was how you sort or filter an entity’s child collection in Linq. For example, if you want to pull a collection of customers, and include all of their orders from this year, but none from earlier, then there doesn’t seem to be a simple way to do this in Linq. You need to do the query in two stages, the first which builds an anonymous type, and the second which links the to parts of it together. See that post for more details.

I also blogged about the problem of Linq not including child entities when doing joins, which requires you to cast the query to an ObjectQuery<> so you can use the Include() method on it.

The problem comes when you want to combine the two methods, meaning that your query needs to be constructed in two stages to ensure that the sorting or filtering of the child collection is done correctly, but you also need to cast the final result to an ObjectQuery<> before you send it out over WCF. The problem arises because you need to enumerate the query before doing the Include(), as that is the only way to ensure that the sorting is done, but calling AsEnumerable() gives you an IEnumerable<> (reasonably enough), which can't be cast to an ObjectQuery! So what's a fellow to do? Good question, and one that had me going for ages.

The only way I have found top do this is to enumerate the collection manually. I added a foreach loop that went through the parent collection and enumerated the children as it went along. I used Debug.Writeline() to dump the results to the Output window, which is one of my favourite debugging techniques. Anyone looking at the code would logically assume that this loop could be removed for the production code (which is I think what happened when I first wrote it), but this would cause the sorting to fail.

I ended up with code like that shown below (read to the end of this blog post to see an improved version of this code). You don’t need to know what the entities represent, just that I wanted a collection of DhrTemplates, each of which has a number of DhrTemplatesPart entities, and these had to be sorted on the DisplayPosition property.

   1:  var dhrTemplatesVar = from dt in getContext().DhrTemplates
   2:                        where dt.CurrentTemplate
   3:                        select new {
   4:                          currentTemplate = dt,
   5:                          templateParts = dt.DhrTemplatesParts.OrderBy(dtp => dtp.DisplayPosition)
   6:                        };
   7:  Debug.WriteLine("Enumerating the collections...");
   8:  foreach (var dtmpl in dhrTemplatesVar) {
   9:    DhrTemplate dt = dtmpl.currentTemplate;
  10:    Debug.WriteLine("PartDefinitionID: " + dt.PartDefinitionID);
  11:    IOrderedEnumerable<DhrTemplatesPart> parts = dtmpl.templateParts;
  12:    foreach (DhrTemplatesPart dtp in parts) {
  13:      Debug.WriteLine("  " + dtp.Description);
  14:    }
  15:  }
  16:  Debug.WriteLine(" ");
  17:  ObjectQuery<DhrTemplate> dhrTemplatesQry = (from dt in dhrTemplatesVar
  18:                                              select dt.currentTemplate) as ObjectQuery<DhrTemplate>;
  19:  if (dhrTemplatesQry != null) {
  20:    ObjectQuery<DhrTemplate> dhrTemplates = dhrTemplatesQry
  21:      .Include("User")
  22:      .Include("PartDefinition")
  23:      .Include("DhrTemplatesParts.PartDefinition.PartInformationTypes");
  24:    List<DhrTemplate> dhrTemplatesCurrent = dhrTemplates.ToList();
  25:    return dhrTemplatesCurrent;
  26:  }
  27:  return null;

The OrderBy clause on line 5 orders the parts correctly, but isn’t in effect until the query is enumerated, which is what happens between lines 8 and 15. I don’t actually need the Debug.WriteLine statements any more, but I left them in case I need to come back to this again. By the time you get to line 17, you still have the anonymous type for the query, but now it has been enumerated, so the sorting is done. Now we can cast it to an ObjectQuery<> and use Include() to include the child entities.

Quite an insidious problem, but obvious when you see the solution. I still have this feeling that there should be a better way to do it though.

Update some time later...

Well of course, there was a much better way to do it! Sadly, I was so stuck in the problem that I missed the blindingly obvious answer. As mentioned, calling AsEnumerable() enumerates the query, but gives you an IEnumerable<>, which can't be cast to an ObjectQuery. However, you don’t have to take the returned value from AsEnumerable(), you can just call it, and carry on using your original query, which has now been enumerated.

This makes the resulting code much simpler...

   1:  var dhrTemplatesVar = from dt in getContext().DhrTemplates
   2:                        where dt.CurrentTemplate
   3:                        select new {
   4:                          currentTemplate = dt,
   5:                          templateParts = dt.DhrTemplatesParts.OrderBy(dtp => dtp.DisplayPosition)
   6:                        };
   7:  dhrTemplatesVar.AsEnumerable();
   8:  ObjectQuery<DhrTemplate> dhrTemplatesQry = (from dt in dhrTemplatesVar
   9:                                              select dt.currentTemplate) as ObjectQuery<DhrTemplate>;
  10:  // rest of the code omitted as it's identical

Notice that lines 7 to 16 in the previous listing have been replaced with the single line 7 in this listing. I’m calling AsEnumerable(), but ignoring the return value. This enumerates the query, but doesn’t leave me with an ObjectQuery.

Pretty obvious really!

Wednesday, 05 October 2011 18:14:00 (GMT Daylight Time, UTC+01:00)

Geographical searches on postcode

I am currently working on an application where I want to have a search feature that allows people to search for businesses within a certain distance of their home (or anywhere else they care to choose).

I have some old UK postcode data knocking around, and was going to use that. For those not familiar with them, UK postcodes are made up of two parts, a major (also known as “outward”) part, and a minor (or “inward”) part. The major part is one or two letters followed by one or two digits, and the minor part is a digit, followed by two letters. Examples of valid postcode formats are M25 0LE, NW11 3ER and L2 3WE (no idea if these are genuine postcodes though).

Coupled with the postcodes are northings and eastings. These odd-sounding beasties are simply the number of metres north and east from a designated origin, which is somewhere west of Lands End. See the Ordinance Survey web site for more details. If you have any two postcodes, you can calculate the distance between them (as the crow flies) by a simple application of Pythagoras’ Theorem. My intention was to use all of this in my search code.

Whilst doing some ferreting around the web, looking for more up-to-date data, I found out that you can now get the UK postcode data absolutely free! When I last looked, which was some years ago admittedly, they charged an arm and a leg for this. Now all you need to do is order it from their downloads page, and you get sent a link to download the data. They have all sorts of interesting data sets there (including all sorts of maps, street views and so on), but the one I wanted was the Code-Point Open set. This was far more up-to-date than the data I had, and was a welcome discovery. Now all I had to do was import it, and write some calculation code.

Before I got any further though, I further discovered that SQL Server 2008 has a new data type known as geography data, which is used to represent real-world (ie represented on a round Earth) co-ordinates. It also has the geometry data type, which is a similar idea, but uses a Euclidean (ie flat) co-ordinate system. Given that I am only dealing with the UK, the curvature of the Earth isn’t significant in distance calculations, and so either data type would do.

However, converting northings and eastings to geography data isn’t as simple as you might hope, but I found a post on Adrian Hill’s blog, where he described how to convert OS data into geometry data, provided a C# console program that does just that, and then showed how easy it is to query the data for distances between points. In other words, exactly what I wanted!

I won’t describe the details here, because you can follow that link and read it for yourself, but basically all you need to do is get the Open-Point data, download the converter and away you go. Truth be told, it wasn’t quite that simple as the format of the data has changed slightly since he wrote the code, so I needed to make a small change. I left a comment on the post, and Adrian updated the code, so you shouldn’t need to worry about that. It doesn’t use hard-coded column numbers anymore, so should be future-proof, in case the OS people change the format again.

Testing the distance calculation, and an important point to improve performance

Once I had the data in SQL Server, I wanted to see how to use it. In the blog post, Adrian showed a simple piece of SQL that did a sample query. You can see the full code on his blog, but the main part of it was a call to an SQL Server function named GeoLocation.STDistance() that did the calculation. He commented that when he tested it, he searched for postcodes within five miles of his home, and got 8354 rows returned in around 500ms. I was somewhat surprised when I tried it to discover that it took around 14 seconds to do a similar calculation! Not exactly what you’d call snappy, and certainly too slow for a (hopefully) busy application.

I was a bit disappointed with this, but decided that for my purposes, it would be accurate enough to do the calculation based on the major part of the postcode only. One of the things Adrian’s code did when importing the data to SQL Server was create rows where the minor part was blank, and the geography value was an average for the whole postcode major area. I adjusted my SQL to do this, and I got results quickly enough that the status bar in SQL Server 2008 Management Studio reported them as zero. OK, so the results won’t be quite as accurate, but at least they will be fast.

Whilst I was writing this blog post, I looked back at Adrian’s description again, and noticed one small bullet point that I had missed. When describing what his code did, he mentioned that it created a spatial index on the geography column. Huh? What on earth (pardon the pun) is a spatial index. No, I had no idea either, so off I went to MSDN, and found an article describing how to create a spatial index. I created one, which took a few minutes (presumably because there were over 17 million postcodes in the table), and tried again. This time, I got the performance that Adrian reported. I don’t know if his code really should have created the spatial index, but it didn’t. However, once it was created, the execution speed was fast enough for me to use a full postcode search in my application.

Bringing the code into the Entity Framework model

So, all armed with working code, my next job was to code the search in my application. This seemed simple enough, just update the Entity Framework model with the new format of the postcodes table, write some Linq to do the query and we’re done… or not! Sadly, Entity Framework doesn’t support the geography data type, so it looked like I couldn’t use my new data! This was a let-down to say the least. Still, not to be put off, I went off and did some more research, and realised that it was time to learn how to use stored procedures with Entity Framework. I’d never done this before, simply because when I discovered Entity Framework, I was so excited by it that I gave up writing SQL altogether. All my data access code went into the repository classes, and was written in Linq.

Creating a stored procedure was pretty easy, and was based on Adrian’s sample SQL:

create procedure GetPostcodesWithinDistance
@OutwardCode varchar(4),
@InwardCode varchar(3),
@Miles int
as
begin
  declare @home geography
  select @home = GeoLocation from PostCodeData
      where OutwardCode = @OutwardCode and InwardCode = @InwardCode
  select OutwardCode, InwardCode from dbo.PostCodeData
  where GeoLocation.STDistance(@home) <= (@Miles * 1609)
    and InwardCode <> ''
end

Using stored procedures in Entity Framework

Having coded the stored procedure, I now had to bring it into the Entity Framework model, and work out how to use it. The first part seemed straightforward enough (doesn’t it always?). You just refresh your model, open the “Stored Procedures” node in the tree on the Add tab, select the stored procedure, click OK and you’re done. Or not. The slight problem was that my fantastic new stored procedure wasn’t actually listed in the tree on the Add tab. It was a fairly simple case of non-presence (Vic wasn’t there either).

After some frustration, someone pointed out to me that it was probably due to the database user not having execute permission on the stored procedure. Always gets me that one! Once I had granted execute permission, the stored procedure appeared (although Vic still wasn’t there), and I was able to bring it into the model. Then I right-clicked the design surface, chose Add –> Function Import and added the stored procedure as a function in the model context. Finally I had access to the code in my model, and could begin to write the search.

Just to ensure that I didn’t get too confident, Microsoft threw another curve-ball at me at this point. My first attempt at the query looked like this:

IEnumerable<string> majors = from p in jbd.GetPostcodeWithinDistance("M7", 45)
 
IQueryable<Business> localBusinesses = from b in ObjSet
          where (from p in majors
                  where p.Major == b.PostcodeMajor
                  select p).Count() > 0
          select b;

The first query grabs all the postcodes within 45 miles of the average location of the major postcode M7.Bear in mind that this query was written before I discovered the spatial index, so it only uses the major part of the postcode. A later revision uses the full postcode. The variable jbd is the context, and ObjSet is an ObjectSet<Business> which is created by my base generic repository.

When this query was executed, I got a delightfully descriptive exception, “Unable to create a constant value of type 'JBD.Entities.Postcode'. Only primitive types ('such as Int32, String, and Guid') are supported in this context.” Somewhat baffled, I turned the Ultimate Source Of All Baffling Problems known as Google, and discovered that this wasn’t actually the best way to code the query, even if it had worked. I had forgotten about the Contains() extension method, which was written specifically for cases like this.

The revised code looked like this (first query omitted as it didn’t change):

IQueryable<Business> businesses = from b in ObjSet
                                  where majors.Contains(b.PostcodeMajor)
                                  select b;

Somewhat neater, clearer and (more to the point) working!

So, with working code, I now only had more hurdle to jump before I could claim this one had been cracked.

Copying geography or geometry data to another database

All of the above was going on on my development machine. Now I had working code, I wanted to put the data on the production server, so that the application could use it. This turned out to be harder than I thought. I tried the SQL Server Import/Export wizard, which usually works cleanly enough, but got an error telling me that it couldn’t convert geography data to geography data. Huh? Searching around for advice, I found someone who suggested trying to do the copy as NTEXT, NIMAGE, and various other data types, but none of these worked either.

After some more searching, I discovered an article describing it, that says that SQL Server has an XML file that contains definitions for how to convert various data types. Unfortunately, Microsoft seem to have forgotten to include the geography and geometry data types in there! I found some code to copy and paste and, lo and behold, it gave the same error message! Ho hum.

After some more messing around and frustrated attempts, I mentioned the problem to a friend of mine who came up with the rather simple suggestion of backing up the development database and attaching it to the SQL Server instance on the production machine. I had thought of this, but didn’t want to do it as the production database has live data in it, which would be lost. He pointed out to me that if I attached it under a different name, I could then copy the data from the newly-attached database to the production one (which would be very easy now that they were both on the same instance of SQL Server), and then delete the copy of the development database. Thank you Yaakov!

Thankfully, this all worked fine, and I finally have a working geographic search. As usual, it was a rough and frustrating ride, but I learned quite a few new things along the way.

Tuesday, 20 September 2011 14:12:00 (GMT Daylight Time, UTC+01:00)
# Wednesday, 07 September 2011

Of course, we professional programmers never make mistakes, ahem. That’s why we never need to use debuggers, ahem.

Well suspend belief for a moment, and assume that I had a bug in the code I was developing. You know the feeling, you stare at it, you write unit tests, you stare at it some more, and still can’t work out why on earth Visual Studio is claiming that there is an error in your code, when it’s so obvious that there isn’t. You even get to the point of talking to your computer, pointing out the error of its ways.

Eventually, you spot the mistake. Once you’ve seen it, it was so blindingly obvious that you can only offer a silent prayer of thanks that no-one else was in the room at the time. You change that one tiny typo, and suddenly Visual Studio stops complaining about your code and it all runs correctly.

Just as you sit back relieved, you notice your computer smirking. I’m certain mine just laughed at me. It did it quietly, but I noticed. It hates me.

Wednesday, 07 September 2011 16:42:00 (GMT Daylight Time, UTC+01:00)