Introduction
Recently, I needed to create a surface app with drag and drop functionality, which is a pretty common thing to do in Microsoft Surface apps (obviously). Anyhow, it took me a while to get a solid understanding of how the whole process worked, so I thought I would try to make it a little easier for everyone else to get up to speed on this.
This is going to be Part 1 of a multi-part tutorial on how to implement drag and drop on Microsoft Surface. In this part, we will add a Surface ListBox and a ScatterView to our Surface window as the basic controls we will need here. We will also see how to use the Amazon.com Web Service to populate your list box with anything you like. We will not get into performing drag and drop in this part, we will simply set ourselves up to do this starting in Part 2 of this series. The complete application of this part can be downloaded at the bottom if you simply want to skip this and get straight to the drag and drop stuff.
For this lab, you will need the following:
- Microsoft Surface SDK installed on your computer; this will give you access to the project templates and the Surface simulator if you don't have your own Surface unit.
- Visual Studio 2008, Professional or Express edition.
- Blend is nice, but optional. I plan to do a tutorial later in this series on styling Surface controls with Blend.
OK, enough talk, let's get started!
Setting up
- Open Visual Studio to the Surface WPF Project template.

- Name your project whatever you like, but mine will be named DragAndDropTutorialPart1.
- Now, drag a
ScatterView control onto your Surface window. Delete all the properties set for the ScatterView except for the Name property which is set by default to scatterView1 (which we will leave as is).
- Next, we will drop a Surface
ListBox control (not a regular WPF ListBox) onto the Surface window as well. At this point, your XAML should look something like:

- We have the basics of our layout defined. Now, let's work on a data source to fill our Surface
ListBox. I am going to show how to use Amazon.com as a product source. Personally, I hate wasting time making and working off of dummy data (especially XML file dummy data) when you can just use real data. You can see a more detailed example of consuming an Amazon Web Service at Amazon.com.
- Download the C# libraries supplied by Amazon.com here.
- Now, we are going to import the project we just found on Amazon into our Solution. Right-click on the Solution node and select "Add", then select "Existing Project". Navigate to the project file for Amazon.ECS, not the samples one. However, you can use the samples Amazon provides to refine your method of getting data if you like.
- Your Solution Explorer window should now look something like this:

- Now, we need to add a reference to our DragAndDropTutorialProject that allows us access to this new library. Right-click on the DragAndDropTutorialProject node (not the solution node we used earlier).
- Then, select "Add Reference". After a few seconds, a new window pops up, which looks like so (after selecting the Projects tab that is):

Since we only have one project to select from, the choice should be easy. Select the Amazon.ECS project and click "OK".
- We are going to put our Amazon Web Request into the
SurfaceWindow.Loaded event handler. This will cause the application to get our Amazon products as soon as the window has loaded. Obviously, you could use many other events available on many other controls if you like. Our XAML should look like this now (I collapsed things we aren't dealing with at the moment, but your ScatterView and ListBox are still there):

The best way to do this (in my humble opinion) is to put your cursor right after the quote marks at the end of the "Title" property. Then, press the spacebar, intellisense will now give you a list of properties and events you can add to your window. Go down to the Loaded event which has a lightning bolt next to it. Select it, now you will see intellisense helping you further by offering to name your new event handler for you, which I let it do for me. One other thing that is being done for you is, VS places the code for the event handler in the C# code-behind file for you. If you open the code-behind file, you should see the following (if you don't for some reason, then add it):

- Now, we want to create a class that we use to define our
Product objects. Right-click on the DragAndDrop project node and choose "Add", then "New Class". Name this class "Product", then click on "OK." Replace the default code in the Product class with the following:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DragAndDropTutorialPart1
{
public class Product
{
private string asin;
private string smallImageUrl;
private string mediumImageUrl;
public string MediumImageUrl
{
get { return mediumImageUrl; }
set { mediumImageUrl = value; }
}
public string SmallImageUrl
{
get { return smallImageUrl; }
set { smallImageUrl = value; }
}
public string ASIN
{
get { return asin; }
set { asin = value; }
}
public Product()
{
}
public Product(string asin, string smallImageUrl,
string mediumImageUrl)
{
this.asin = asin;
this.smallImageUrl = smallImageUrl;
this.mediumImageUrl = mediumImageUrl;
}
}
}
- Now, we want to create a class using the
ObservableCollection type where our listbox will eventually get its data. This class will hold a collection of Product objects we will create from our Web Service call. The reason we will inherit from ObservableCollection is because this class has logic built in for notifying our user interface of changes to the data, so the UI can then update itself. Right-click on the DragAndDrop project node, and choose "Add", then "New Class". Name this class ProductCollection, then click on "OK".
- Change the default class code (of
ProductCollection) to look like this:

Now, we are going to load our ProductCollection with products, which will eventually be showing in our listbox. I should point out that a lot of code is going into this one class that would probably be separated among multiple classes in a real production application. This tutorial is to show the basics of drag and drop on Surface, not proper application architecture.
- Now, we need to place a method in our
ProductCollection class which will retrieve a list of products from our Amazon Web Service. Create the following method:
public void GetAmazonProducts()
{
String accessKeyId = "123WQY86NSWRDKDQRGR2";
String associateTag = "visusear-20";
AmazonECS service = new AmazonECSQuery(accessKeyId, associateTag);
ItemSearchRequest request = new ItemSearchRequest();
request.SearchIndex = "Books";
request.Author = "King";
List<string> responseGroupString = new List<string>();
responseGroupString.Add("Medium");
request.ResponseGroup = responseGroupString;
InvokeItemSearch(service, request);
}
Note: I left in my accessKeyId and associateTag if you don't feel like signing up for your own. If you do sign up for your own, then you would replace these two values with the ones Amazon gives you.
- Now, the astute reader will notice that we have not implemented
InvokeItemSearch yet. Here is the method for that, which you add to your product collection class as well:
public void InvokeItemSearch(AmazonECS service, params ItemSearchRequest[] request)
{
try
{
ItemSearchResponse response = service.ItemSearch(request);
List<Items> itemsList = response.Items;
foreach (Items items in itemsList)
{
List<Item> itemList = items.Item;
foreach (Item item in itemList)
{
Product product = new Product();
if (item.IsSetASIN())
{
product.ASIN = item.ASIN;
}
if (item.IsSetSmallImage())
{
product.SmallImageUrl = item.SmallImage.URL;
}
if (item.IsSetMediumImage())
{
product.MediumImageUrl = item.MediumImage.URL;
}
this.Add(product);
}
}
}
catch (AmazonECSException ex)
{
}
}
Note: I put in try/catch blocks as Web Service requests are a great place to introduce exceptions into your code. In this case, we are just "eating" the exception without dealing with it. Good coders would never do this in production code, they would add code inside the catch block dealing with the problem in one way or another. Our complete ProductCollection class should look like this now (I collapsed the content of the previous two methods to save space):

- Now, go to SurfaceWindow1.xaml.cs and add the following right after the opening brace of the class:
private ProductCollection productCollection;
- Inside the constructor, add the following line:
productCollection = new ProductCollection();
The top part of your SurfaceWindow1 class should now look something like:

- Now, let's bind the data to our listbox. Change the XAML on your listbox to go from this:
<s:SurfaceListBox HorizontalAlignment="Left" Name="surfaceListBox1"/>
to this:
<s:SurfaceListBox HorizontalAlignment="Left"
Name="surfaceListBox1" ItemsSource="{Binding}"/>
- Now we need to add logic in our Window
Loaded event handler to cause the ProductCollection to be filled. The second line sets the DataContext of the Surface window to the productCollection instance. By calling {Binding} on the ItemsSource property of the listbox, the listbox gets its data from the Surface window's DataContext property.
private void SurfaceWindow_Loaded(object sender, RoutedEventArgs e)
{
productCollection.GetAmazonProducts();
this.DataContext = productCollection;
}
- Now, let's hit F5 and see our Amazon products in our
ListBox! Oh wait, nothing is showing up in our ListBox. What could be wrong? Our ListBox has no idea how to display our products. We need to give it further information.
- Add the listbox style and
DataTemplate for each item to the SystemWindow.Resources node. Download the text file containing these resources from the file list at the bottom of this tutorial, as the content is quite long. I plan to do a tutorial in the future on how to create all this from Blend. Substitute the SurfaceWindow.Resources node with the content you find there. Like I mentioned before, this tutorial is about drag and drop, so we'll save Blend for another day.
- After you have added all our cool new
ListBox and DataTemplate styling, change the XAML of your ListBox to this:
<s:SurfaceListBox x:Name="surfaceListBox1"
ItemTemplate="{DynamicResource ProductDataTemplate}"
Style="{StaticResource ProductListStyle}"
ItemsSource="{Binding}" />
- Now, if we run our application, we should see this:

Wow! We got a lot accomplished, but we still haven't even gotten to the drag and drop stuff yet. In the next part of this series, we will drag items from our listbox, drop them onto the ScatterView, then have fun manipulating them. Go reward yourself with an age appropriate beverage, then we'll get started on Part 2.
Also, if anything wasn't clear, or if there is some way you think I could improve this tutorial, please offer a constructive comment.