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:
OK, enough talk, let's get started!

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). ListBox control (not a regular WPF ListBox) onto the Surface window as well. At this point, your XAML should look something like:
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. 

Since we only have one project to select from, the choice should be easy. Select the Amazon.ECS project and click "OK".
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):

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;
}
}
}
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". 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.
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.
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)
{
//This is the loop where we build each product object.
//So let's create a new Product object here.
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;
}
//now add this newly created product to this
//class which is an ObservableCollection.
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):

private ProductCollection productCollection;
productCollection = new ProductCollection();
The top part of your SurfaceWindow1 class should now look something like:

<s:SurfaceListBox HorizontalAlignment="Left" Name="surfaceListBox1"/>
to this:
<s:SurfaceListBox HorizontalAlignment="Left"
Name="surfaceListBox1" ItemsSource="{Binding}"/>
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;
}
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. 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. 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}" />

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.
| You must Sign In to use this message board. | ||||||||||||||||
|
||||||||||||||||
|
||||||||||||||||
|
||||||||||||||||