Someone on the Atlas forums had a great idea to show customer data in a ListView and display a map which centers to the location of the customer's country. I slightly modified his idea and came up with a demo which demonstrates several concepts such as bindings and actions.
Before we go through the code, you probably should take a look at the results first. You may also be interested in the source code for this demo. Note: I use a modified version of AtlasUIMap.js which fixes a few bugs. Please use the AtlasUIMap.js from this download if you want to try and build this demo yourself (at least until Microsoft releases an update which fixes these issues).
Step 1: Build the service
Ok, so now you've seen what can be done, we can take a look at how we actually did it. The first is to create a simple data service which exposes our customer data. Since I find binding against a data source currently the easiest way to get data from the server in for example a ListView, I create a web service that derives from Microsoft.Web.Services.DataService.
The first method that we expose is a data-service method that the DataSource uses to select data. We have to decorate it with a DataObjectMethod attribute, so the Atlas proxy for the DataSource knows which method to call to select data. This method returns an array of Customer objects. We can define such an object simply by creating it, and decorate the properties that should be accessible on the client with the DataObjectField attribute.
The second method we expose is to return suggestions to the auto complete textbox. It is important to note that this signature needs to be pretty exact. Especially the parameters (prefixText and count).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
public class Customer {
private string name;
// Make this property accessible for the client-side.
[DataObjectField(false)]
public string Name {
get {
return this.name;
}
}
}
// Specify that this method is the data-selection method that
// the DataSource proxy call.
[DataObjectMethod(DataObjectMethodType.Select)]
[WebMethod]
public Customer[] GetData(string country) {
//
}
|
Step 2: Query the service
The next thing we should do is query the service. We can do this by adding a data source control to our page. Then add a TextBox control and point the AutoCompletion method to the method that we added to our service. After this is done, we can set up the binding between the DataSource and the TextBox, to specify what argument we want to pass to the service when we search for customers. To actually query the service, we should call the DataSource's select method when we press our search button. We can do this declaratively by using actions. Specifically, we use an InvokeMethod action, which can invoke a method of a component on our page.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<atlas:DataSource ID="customerDataSource" runat="server" ServiceUrl="CustomerService.asmx">
<Bindings>
<atlas:Binding DataContext="countryTextBox" DataPath="text"
Property="selectParameters" PropertyKey="country" />
</Bindings>
</atlas:DataSource>
<atlas:TextBox ID="countryTextBox" runat="server" AutoCompletionServiceUrl="CustomerService.asmx"
AutoCompletionServiceMethod="GetSuggestions" AutoCompletionMinimumPrefixLength="1" />
<atlas:Button runat="server" Text="Search">
<Click>
<Actions>
<atlas:InvokeMethodAction Target="customerDataSource" Method="select" />
</Actions>
</Click>
</atlas:Button>
|
Step 4: Add a ListView to display the customers
We're almost there. To display the results (ie. the contents of the DataSource), we add the ListView control and define how it should display its data. Additionally, we also bind the ListView to the DataSource.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<atlas:ListView ID="customerListView" runat="server" ItemTemplateControlID="customer">
<Bindings>
<atlas:Binding DataContext="customerDataSource" DataPath="data" Property="data" />
</Bindings>
<LayoutTemplate>
<div id="customerContainer" runat="server">
<div id="customer" runat="server">
<atlas:Label runat="server">
<Bindings>
<atlas:Binding DataPath="Name" Property="text" />
</Bindings>
</atlas:Label>
</div>
</div>
</LayoutTemplate>
<EmptyTemplate>
No customers to display.
</EmptyTemplate>
</atlas:ListView>
|
Step 5: Add a VirtualEarthMap to display the customers
Lastly, we add another view of our customer data, by adding a VirtualEarth control to our page. Again, all we need to do is add a binding and define what it should look like. Note that some properties like DataLatitudeField and DataLongitudeField default to 'Latitude' and 'Longitude' respectively, so you don't have to specify those if those are the names that you use in your data source.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<atlas:VirtualEarthMap ID="map" runat="server" Latitude="22" Longitude="-100"
MapStyle="Hybrid" ZoomLevel="9" CssClass="map" DataValueField="ID"
DataTextField="Name" PushpinCssClass="pushpin" PushpinActivation="Hover">
<Bindings>
<atlas:Binding DataContext="customerDataSource" DataPath="data" Property="data" />
</Bindings>
<PopupTemplate>
<div style="background-color: white; border: 1px solid black">
<atlas:Label runat="server">
<Bindings>
<atlas:Binding DataPath="Name" Property="text" />
</Bindings>
</atlas:Label>
</div>
</PopupTemplate>
</atlas:VirtualEarthMap>
|
Bonus step: Connect the customer in the ListView with the customer on the map
If you want, you can add a 'locate on map' button to the ListView, which takes you to the selected customer on the map. All you need to do is invoke a method on the map, 'panTo', and add 2 bindings to specify what arguments should be passed to this method (latitude and longitude values).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<atlas:Button runat="server" Text="Locate on map">
<Click>
<Actions>
<atlas:InvokeMethodAction Target="map" Method="panTo">
<Bindings>
<atlas:Binding DataPath="sender.dataContext.Latitude"
Property="parameters" PropertyKey="latitude" />
<atlas:Binding DataPath="sender.dataContext.Longitude"
Property="parameters" PropertyKey="longitude" />
</Bindings>
</atlas:InvokeMethodAction>
</Actions>
</Click>
</atlas:Button>
|
Hopefully you will find this useful to get some idea of what kind of cool stuff you can do with Atlas already. If you feel that I went through this way too quick, please leave behind a comment and let me know if there is anything in particular that you would like me to explain in more depth.