Bind customer data to different views using Atlas

Posted at Thu, 06 Oct 2005 23:48:36 GMT by Wilco Bauwer

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).

C#:
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.

ASP.NET:
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.

ASP.NET:
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.

ASP.NET:
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).

ASP.NET:
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.

Thanks for the example Wilco! You always make it look so easy. Once I understand Web Services I think I will be able to make much better use of it:)
Personally I like the ASP.NET/Google maps implementation better. One has more control to flip between actual views of satellite pictures, Google maps, and a combo of the two. Then one can add virtual thumbtacks that when clicked presents the user with more info. You can fly in and out, or use a set of buttons to move in any direction, whereas this implementation requires a lot of scrolling.

Bill Pierce's 3-part articles can be found at
www.codeproject.com at

1) http://www.codeproject.com/aspnet/LatLaysFlat-Part1.asp

2) http://www.codeproject.com/aspnet/LatLaysFlat-Part2.asp

3) http://www.codeproject.com/aspnet/LatLaysFlat-Part3.asp

Darran
Darran,

The VE control doesn't prevent you from doing these things. In fact, Atlas has a MapTemplate which lets you overlay anything on top of the map. Atlas ships with a 'MapController' which you could put inside this template, which will make it possible to use a GUI to navigate your map and switch views.

This control can also let you click on a pushpin to present more information. All that you'd have to change is set the PushpinActivation property of the map to 'Click'. In the demo in this post I made a very basic 'popup', but ofcourse one could style this and for example display a nice balloon.
Hi ,
I have to use my own database of .shp files.
can i use the virtual earth server control to show these images?How?
sanket
Hi Wilco,
I have VS 2005 RTM and tried to run your example. First, it didn't recognize appliedTo attribute in web.config. When I removed the attribute (because Web value is default anyhow) I get the runtime error (see below). What did I do wrong?

By the way, we are trying to use some browser client callbacks technology in December. We are debating between AJAX and ATLAS. We are in favor of ATLAS, but, is it going to be ready for at least basic functionality? What is your opinion?

Thanks Dragan

Here is the error:

Server Error in '/Code' Application.
--------------------------------------------------------------------------------

Field not found: 'System.Collections.Generic.KeyValuePair`2.Key'.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.MissingFieldException: Field not found: 'System.Collections.Generic.KeyValuePair`2.Key'.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:


[MissingFieldException: Field not found: 'System.Collections.Generic.KeyValuePair`2.Key'.]
Microsoft.Web.UI.ScriptManager.RenderScriptScript() +0
Microsoft.Web.UI.ScriptManager.OnPagePreRenderComplete(Object sender, EventArgs e) +42
System.EventHandler.Invoke(Object sender, EventArgs e) +0
System.Web.UI.Page.OnPreRenderComplete(EventArgs e) +96
System.Web.UI.Page.PerformPreRenderComplete() +32
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +4796




--------------------------------------------------------------------------------
Version Information: Microsoft .NET Framework Version:2.0.50727.26; ASP.NET Version:2.0.50727.26
You are probably using the Beta 2 bits of Atlas, which won't work on RC/RTM. Go to http://atlas.asp.net for a link to the bits for RTM.

Currently, Atlas is just a preview and can/should not be used in production environments. I think Microsoft said we can expect a release in about 6 months or something.
Am I supposed to find all customers located somewhere in central Mexico?
Can you use your own map, say I wanted to do a map of the office with staff as pushpins, could I achieve this using AtlasUIMap.js and Atlas or can I only use Virtual Earth for the map?
Hi,

I've a List View Control that gets its data from a webservice. In each row I want to have an Edit hyperlink which calls a javacsript function which requires all the values in that row as parameters. Can anyone please tell me how to bind the values in each row as parameters to the javscript function ?

<page xmlns:script="http://schemas.microsoft.com/xml-script/2005">
<components>
<dataSource id="listDataSource" autoLoad="true" serviceURL="XmlService.asmx" />
<listView id="myList" itemTemplateParentElementId="myList_itemTemplateParent">
<bindings>
<binding dataContext="listDataSource" dataPath="data" property="data" />
</bindings>

So I want I essentially want to do is , have a Sys.UI.HyperLink control call a javascript function with parameters when clicked on it. Kindly tell me how to specify parameters for the HyperLink control.

<hyperLink id="linkEdit2" click="makeQueryString">

Thanks in advance,
Anu

Hi wilco,

Could you update your dragdrop code to work with ASP AJAX Beta 1? I realize dragdrop is not part of the core package but when I downloaded the ASP AJAX CTP which provides the "Preview" features, I noticed the dragdrop functionality has been consolidated and altered which prevents your code among others from working. Its unfortunate that there is no information in the SDK to tell us how to get started with drag and drop. I imagine alot of people want to get started but without documentation its pretty difficult.

Andrew
Dear Wilco,

Have you tried listview data binding with web services in Atlas Beta 1? If so, could you please post a sample?

Thanks.
Your message will be encoded/formatted when it is displayed. If you want to post code, please put the code inside [code=X][/code] tags, where X is the language of your code (C#, ASPX, SQL, etc).
Name:
Email:
(will be encoded using JavaScript to keep it functional and prevent it from being picked up by spammers)
Url:
 
Message:
3 + 3 =