My musings about .NET and what not

Nested ListViews and More - Working with Databound Controls Inside the ListView

To take full advantage of all the great stuff the ListView has to offer, it's important to understand how to properly bind controls that are nested inside of it. Once you know how, it's easy to embed any data-bound control like DropDownLists, CheckBoxLists, and even other ListViews inside your ListView. Here, I'm going to demonstrate two different ways to do this.

As we all know, the ListView is the new, super-duper data bound control that Microsoft introduced with ASP.NET 3.5. You could think of the ListView as what you might get if a GridView and a Repeater had a baby. Like the GridView, the ListView can display, select, edit, delete, page, and sort records. And like the Repeater, the ListView is entirely template-driven. Also, the ListView supports inserting new records, functionality provided by neither the GridView nor the Repeater.

The ListView is just so fun-n-flexible, I call it the Gumby of Data Bound Controls. Once it finds its way into your toybox, you'll want to play with it every chance you get.

The Problem

Let's pretend you're building a blog-like application. You would probably want to have a page that shows a list of your blog articles. That could be a ListView. And under each article, you'd want to have a list of tags for that article. That list of tags could also be a ListView. The tags ListView would be nested inside the articles ListView.

You might end up with something like the following:

Figure 1

How would you approach this? Well, binding the outer ListView (the articles) is not very tricky at all. You could use an ObjectDataSource, an SqlDataSource, a  LinqDataSource -- in fact, any data source control you want. Configure the data source control, specify its DataSourceID in the ListView, throw down a few databinding expressions, and bada bing! -- you're halfway home.

<%@ Page Language="C#" %>
 
DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
   <title>Articlestitle>
head>
<body>
   <form id="form1" runat="server">
      <div>         
         <asp:ListView ID="lvArticles" runat="server" DataSourceID="objArticles"
            ItemPlaceholderID="itemPlaceHolder1">
            <ItemTemplate>
               <p>
                  <asp:Label ID="lblArticleTitle" runat="server" Font-Bold="true"
                     Text='<%# Eval("Title") %>' />
                  <br />
                  <asp:Label ID="lblPublishedDate" runat="server" Font-Italic="true"
                     Text='<%# Eval("PublishedDate","{0:MMM d, yyyy}") %>' />
                  <br />
                  Tags:                  
                  <asp:ListView ID="lvTags" runat="server" ItemPlaceholderID="itemPlaceHolder2" >
                     <ItemTemplate>
                        <asp:Label ID="lblTagName" runat="server" Text='<%# Eval("TagName") %>' />
                     ItemTemplate>
                     <LayoutTemplate>
                        <asp:PlaceHolder ID="itemPlaceHolder2" runat="server" />
                     LayoutTemplate>
                  asp:ListView>
               p>
            ItemTemplate>
            <LayoutTemplate>
               <asp:PlaceHolder ID="itemPlaceHolder1" runat="server" />
            LayoutTemplate>
         asp:ListView>
         <asp:ObjectDataSource ID="objArticles" runat="server" SelectMethod="GetArticles"
            TypeName="LD.Blog.Article" />
      div>
   form>
body>
html>

Figure 2

In Figure 2, we're using an ObjectDataSource (objArticles) to bind the outer ListView (lvArticles). Of course, this assumes I've set up a class called LD.Blog.Article, that contains a method called GetArticles that returns article data.

using System;
using System.Collections.Generic;
 
namespace LD.Blog
{
   public class Article
   {
      public int ArticleID { get; set; }
      public string Title { get; set; }
      public DateTime PublishedDate { get; set; }
      public static IEnumerable
GetArticles()
      {
         // data access code not shown
      }
   }
}

Figure 3

I've purposely left out the specific data access code from Figure 3. It's not important exactly how we're fetching the data in the GetArticles method. This could be LINQ to SQL, classic ADO.NET, or whatever. All that matters is that we're returning a collection of Article objects that the lvArticles ListView can bind to.

Notice also from Figure 2 that we've nested a second ListView (lvTags) inside the of lvArticles. This what we have so far:

Figure 4

Of course, there are no tags showing. That's because we haven't bound the inner lvTags ListView to anything yet. Let's see what we have to do to accomplish that.

Solution 1: Using a Second DataSource Control

Let's further assume you also have a class called LD.Blog.Tag that contains a method called GetTagsByArticle. This method takes as an argument the ID of an article, and returns the Tags belonging to that Article.

using System.Collections.Generic;
 
namespace LD.Blog
{
   public class Tag
   {
      public int TagID { get; set; }
      public string TagName { get; set; }
      public static IEnumerable GetTagsByArticle(int articleID)
      {
         // data access code not shown
      }
   }
}

Figure 5

Given this, it would be natural to assume we could just embed a second ObjectDataSource into lvArticles and bind lvTags to that -- and of course, we can.

<%@ Page Language="C#" %>
 
DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
   <title>Articles - Nested ListView, ObjectDataSourcetitle>
head>
<body>
   <form id="form1" runat="server">
      <div>
         <asp:ListView ID="lvArticles" runat="server" DataSourceID="objArticles"
            ItemPlaceholderID="itemPlaceHolder1" OnItemDataBound="lvArticles_ItemDataBound">
            <ItemTemplate>
               <p>
                  <asp:Label ID="lblArticleTitle" runat="server" Font-Bold="true"
                     Text='<%# Eval("Title") %>' />
                  <br />
                  <asp:Label ID="lblPublishedDate" runat="server" Font-Italic="true"
                     Text='<%# Eval("PublishedDate","{0:MMM d, yyyy}") %>' />
                  <br />
                  Tags:
                  <asp:ListView ID="lvTags" runat="server" ItemPlaceholderID="itemPlaceHolder2"
                     DataSourceID="objTags">
                     <ItemTemplate>
                        <asp:Label ID="lblTagName" runat="server" Text='<%# Eval("TagName") %>' />
                     ItemTemplate>
                     <LayoutTemplate>
                        <asp:PlaceHolder ID="itemPlaceHolder2" runat="server" />
                     LayoutTemplate>
                  asp:ListView>
                  <asp:ObjectDataSource ID="objTags" runat="server" SelectMethod="GetTagsByArticle"
                     TypeName="LD.Blog.Tag">
                     <SelectParameters>
                        <asp:Parameter Name="articleID" />
                     SelectParameters>
                  asp:ObjectDataSource>
               p>
            ItemTemplate>
            <LayoutTemplate>
               <asp:PlaceHolder ID="itemPlaceHolder1" runat="server" />
            LayoutTemplate>
         asp:ListView>
         <asp:ObjectDataSource ID="objArticles" runat="server" SelectMethod="GetArticles"
            TypeName="LD.Blog.Article" />
      div>
   form>
body>
html>

Figure 6

You see that this new ObjectDataSource (we've named it objTags) uses the GetTagsByArticle method, which requires articleID as an argument, as indicated by the <SelectParameters> collection. Now, we just need a way to get the ArticleID of each article being bound, and pass it to the parameter.

The underlying data object that a ListViewItem object is bound to is contained in the ListViewDataItem.DataItem property. You need access to this property in order to get the ArticleID you need to pass as an argument. Now, according to the MDSN, the DataItem property is only available during and after the ItemDataBound event of a ListView control. That isn't exactly true, as DataItem is also available during the ItemCreated event. (I suspect that this functionality may have been added at the last minute, and the MSDN docs weren't updated to reflect the change. Hey, stuff like that happens sometimes.) Anyway, for this example it doesn't really matter; we can use either event. So, let's use ItemDataBound.

protected void lvArticles_ItemDataBound(object sender, ListViewItemEventArgs e)
{
   if (e.Item.ItemType == ListViewItemType.DataItem)
   {
      ListViewDataItem dataItem = (ListViewDataItem)e.Item;
      Article article = (Article)dataItem.DataItem;
      ObjectDataSource objTags = (ObjectDataSource)e.Item.FindControl("objTags");
      Parameter parameter = objTags.SelectParameters[0];
      parameter.DefaultValue = article.ArticleID.ToString();
   }
}

Figure 7

You can see what's happening in Figure 7. As each item in lvArticles is bound, a reference to the item is obtained using the ListViewItemEventArgs.Item property. If that item is of type DataItem, it's cast to type ListViewDataItem. Then, the DataItem property of this ListViewDataItem is cast to type Article. A reference to the nested ObjectDataSource is obtained, the parameter is plucked from its SelectParameters collection, and the DefaultValue of the parameter is set to the ArticleID of the article just bound. Once you run this, you should see the output shown in Figure 1. And we're done!

Piece of cake, right? Well, as they say on those late-night infomercials: But wait! There's more! Let's investigate a different way to do this that doesn't involve a second ObjectDataSource, or even require us to handle any events.

Solution 2: Using a Databinding Expression

As the old saying goes, there's more than one way to skin a cat -- just like there's more than one way to bind a control to data. Instead of using DataSourceID to wire up to a data source control, you can use DataSource to bind directly to an data object. You can set the DataSource property in code, or you can set it declaratively using a databinding expression.

<%@ Page Language="C#" %>
 
DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
   <title>Articles - Nested ListView, Databinding Expression (Direct)title>
head>
<body>
   <form id="form1" runat="server">
      <div>
         <asp:ListView ID="lvArticles" runat="server" DataSourceID="objArticles"
            ItemPlaceholderID="itemPlaceHolder1">
            <ItemTemplate>
               <p>
                  <asp:Label ID="lblArticleTitle" runat="server" Font-Bold="true"
                     Text='<%# Eval("Title") %>' />
                  <br />
                  <asp:Label ID="lblPublishedDate" runat="server" Font-Italic="true"
                     Text='<%# Eval("PublishedDate","{0:MMM d, yyyy}") %>' />
                  <br />
                  Tags:
                  <asp:ListView ID="lvTags" runat="server" ItemPlaceholderID="itemPlaceHolder2"
                     DataSource='<%# LD.Blog.Tag.GetTagsByArticle((int)Eval("ArticleID")) %>'>
                     <ItemTemplate>
                        <asp:Label ID="lblTagName" runat="server" Text='<%# Eval("TagName") %>' />
                     ItemTemplate>
                     <LayoutTemplate>
                        <asp:PlaceHolder ID="itemPlaceHolder2" runat="server" />
                     LayoutTemplate>
                  asp:ListView>
               p>
            ItemTemplate>
            <LayoutTemplate>
               <asp:PlaceHolder ID="itemPlaceHolder1" runat="server" />
            LayoutTemplate>
         asp:ListView>
         <asp:ObjectDataSource ID="objArticles" runat="server" SelectMethod="GetArticles"
            TypeName="LD.Blog.Article" />
      div>
   form>
body>
html>

Figure 8

Here, lvTags.DataSource uses a databinding expression to call the LD.Blog.GetTagsByArticle method directly, passing in an ArticleID obtained via the Eval method. More than likely however, you'd encapsulate this call into a property of your Article class. So let's go ahead and define a property that does just that:

using System;
using System.Collections.Generic;
 
namespace LD.Blog
{
   public class Article
   {
      public int ArticleID { get; set; }
      public string Title { get; set; }
      public DateTime PublishedDate { get; set; }
 
      private IEnumerable tags;
      public IEnumerable Tags
      {
         get
         {
            if (tags == null)
            {
               tags = Tag.GetTagsByArticle(this.ArticleID);
            }
            return tags;
         }
      }
 
      public static IEnumerable
GetArticles()
      {
         // data access code not shown
      }
   }
}

Figure 9

In Figure 9, we've added a property to the Article class called Tags which contains the tags associated with an article. This lets us simplify the databinding expression a little bit:

<%@ Page Language="C#" %>
 
DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
   <title>Articles - Nested ListView, Databinding Expression (Property)title>
head>
<body>
   <form id="form1" runat="server">
      <div>
         <asp:ListView ID="lvArticles" runat="server" DataSourceID="objArticles"
            ItemPlaceholderID="itemPlaceHolder1">
            <ItemTemplate>
               <p>
                  <asp:Label ID="lblArticleTitle" runat="server" Font-Bold="true"
                     Text='<%# Eval("Title") %>' />
                  <br />
                  <asp:Label ID="lblPublishedDate" runat="server" Font-Italic="true"
                     Text='<%# Eval("PublishedDate","{0:MMM d, yyyy}") %>' />
                  <br />
                  Tags:
                  <asp:ListView ID="lvTags" runat="server" ItemPlaceholderID="itemPlaceHolder2"
                     DataSource='<%# Eval("Tags") %>' >
                     <ItemTemplate>
                        <asp:Label ID="lblTagName" runat="server" Text='<%# Eval("TagName") %>' />
                     ItemTemplate>
                     <LayoutTemplate>
                        <asp:PlaceHolder ID="itemPlaceHolder2" runat="server" />
                     LayoutTemplate>
                  asp:ListView>
               p>
            ItemTemplate>
            <LayoutTemplate>
               <asp:PlaceHolder ID="itemPlaceHolder1" runat="server" />
            LayoutTemplate>
         asp:ListView>
         <asp:ObjectDataSource ID="objArticles" runat="server" SelectMethod="GetArticles"
            TypeName="LD.Blog.Article" />
      div>
   form>
body>
html>

Figure 10

If you run the page in Figure 10 using the same data, you'll see the results are identical to those obtained in the first solution, as shown in Figure 1.

Nesting Other Databound Controls in the ListView

Of course, these techniques aren't at all limited to nested ListViews. You can use them to bind any databound control inside a ListView. For example, we can show the tags as an unordered list using the BulletedList control.

<%@ Page Language="C#" %>
 
DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
   <title>Articles - Nested BulletedList, Databinding Expression
   title>
head>
<body>
   <form id="form1" runat="server">
      <div>
         <asp:ListView ID="lvArticles" runat="server" DataSourceID="objArticles"
            ItemPlaceholderID="itemPlaceHolder1">
            <ItemTemplate>
               <p>
                  <asp:Label ID="lblArticleTitle" runat="server" Font-Bold="true"
                     Text='<%# Eval("Title") %>' />
                  <br />
                  <asp:Label ID="lblPublishedDate" runat="server" Font-Italic="true"
                     Text='<%# Eval("PublishedDate","{0:MMM d, yyyy}") %>' />
                  <br />
                  Tags:
                  <asp:BulletedList ID="blTags" runat="server" DataSource='<%# Eval("Tags") %>'
                     DataTextField="TagName" />
               p>
            ItemTemplate>
            <LayoutTemplate>
               <asp:PlaceHolder ID="itemPlaceHolder1" runat="server" />
            LayoutTemplate>
         asp:ListView>
         <asp:ObjectDataSource ID="objArticles" runat="server" SelectMethod="GetArticles"
            TypeName="LD.Blog.Article" />
      div>
   form>
body>
html>

Figure 11

Using the same data, this yields the following output:

Figure 12

As you can see, nesting databound controls inside the ListView, including other ListViews, isn't difficult at all. Hope this helps some of you out there put the ListView to good use. Happy databinding!

EDIT: A couple of readers have asked for the source code for this post, so here you go.

Subscribe to this blog for more cool content like this!

kick it on DotNetKicks.com

shout it on DotNetShoutOut.com

vote it on WebDevVote.com

Bookmark / Share

    » Similar Posts

    1. Master / Detail Editing With a ListView and DetailsView
    2. Resetting the Page Index in a ListView
    3. Building a TweetThis Extension with Automatic Bit.ly for Graffiti CMS

    » Trackbacks & Pingbacks

    1. You've been kicked (a good thing) - Trackback from DotNetKicks.com

      Nested ListViews and More - Databound Controls Inside the ListView — February 15, 2009 11:56 AM
    Trackback link for this post:
    http://leedumond.com/trackback.ashx?id=42

    » Comments

    1. Mark Nordin avatar

      This is one of the best articles on using the List view control; I really appreciate you taking the time to put this out. If you put out a book. I would be the first in line to buy it!

      Mark Nordin — March 17, 2009 4:59 PM
    2. Lee Dumond avatar

      Thanks! If you really like the writing, be sure to let my boss at Wrox Publishing know by posting a reply to this thread on the Wrox programmer forums. ;-)

      Lee Dumond — March 17, 2009 5:05 PM
    3. Greg Burman avatar

      Great stuff ! Goodbye Gridview! I am working on an Ajax project and was struggling with exactly this - I still have to figure out how to bind the nested ListViews on-demand (any ideas?) but this is a great start!

      Greg

      PS - big Wrox fan!

      Greg Burman — April 21, 2009 7:49 PM
    4. Marius C. avatar

      Now that's an article well written, nothing trivious, but is a perfect sample on how should make people understand differences.

      Good work,

      Marius C.

      Marius C. — April 22, 2009 6:15 AM
    5. Tony D. avatar

      Is there a way to download the sourec code for this example with the data access code.

      Tony D. — September 1, 2009 2:52 PM
    6. Lee Dumond avatar

      Tony -- not sure why the data access code matters, but let me see if I can dig it up and zip it to you.

      Lee Dumond — September 1, 2009 4:05 PM
    7. Tony D. avatar

      I am still learning, so I apologize in advance. What I am confused about is how does the objectdatasource get the ArticleID. If you have a static method, I am not sure how to pass the articleID to the public field ArticleID. Thank you for responding to my comment. I am sure you are busy so I appreciate your time.

      Thanks

      Tony D. — September 2, 2009 8:23 AM
    8. Lee Dumond avatar

      Tony: the "passing" of articleID takes place in the lvArticle_ItemDataBound event, which fires for each item in the list. First, the article being bound in each item is determined. Then, the value of the SelectParameter of the nested ODS is set to the ArticleID of the article found. The ODS then takes care of passing this parameter to its Select method.

      I have now provided a link to the source code at the end of the post.

      Lee Dumond — September 3, 2009 4:18 PM
    9. Tom avatar

      How would you take that example and add update / insert /delete editing capability to it. With all the binding pointing to objects and the object refs handling the fetching...how do we then wire up our save (both new and edit) and delete methods of the objects preserving the relationship. Meaning let the user delete a tag, individually. Also, if a user deletes an article all the tags should go as well. Assuming we have the methods all ready...how do wire up? This article is fantastic, this would make it incredible

      Tom — November 12, 2009 7:56 PM
    10. ld1337 avatar

      Unfortunately, I think you made a major mistake in your solution #1. Depending on elements beyond control, the outer ListView ItemDataBound event might fire AFTER the inner ListView is done binding. Therefore, you can't rely on that event to prepare the parameter for your inner ListView. This is the case in my project right now.

      ld1337 — April 2, 2010 8:30 PM
    11. Maxisam avatar

      Oh my, what a masterpiece ! Thank you, man.

      Maxisam — June 1, 2010 4:48 PM
    12. Jay avatar

      Dear Lee,

      I see you example uses data-retrieval code in the datacontainers Article and Tags.

      I am also in the situation where I require nested ListViews to display data in a grouped way, such as what you are doing here.

      I am building a client that communicates with a webservice. There will be no direct connection to the database.

      The webservice returns to me a data structure similar to Articles/Tags. This data structure is just 2 good old fashioned data containers that do not have any data-retrieval code themselves. They are just data containers and nothing more.

      Is it possible to bind these datacontainers to the datasources in the nested ListViews so that I can display my data?

      I want to be able to manually load new data into my datacontainers, then rebind it to the ListView.

      I have found thousands of examples on the web. None of them do exactly that which I am looking for. Please advise.

      Sincerely,

      Jay

      Jay — June 9, 2010 6:07 AM
    13. Kevin avatar

      Nice one Lee! Appreciated.

      Kevin — August 16, 2010 9:43 AM
    14. Sylvia avatar

      This is a great article. I have the nested listview working great, setting the parameter in the ItemDataBound event.

      I have the nested listview in a collapsiblePanelExtender so the user can hide and show that data as needed. This worked great, and was exactly what the customer want. However, I was using just a small amount of test data. With more data added, the page loads far to slow.

      I'd like to be able to load individual nested listviews only when the user clicks on the associated row of parent listview.

      I can do this if I create a separate listview below the parent listview, but the customer really likes the look of the collapsible listview.

      Any ideas?

      Sylvia — January 18, 2011 12:50 PM
    15. Lee Dumond avatar

      @Sylvia -- if you want this to load fast, you probably need to load the data on demand using Ajax.

      Lee Dumond — January 18, 2011 12:58 PM
    16. Sylvia avatar

      Thanks for the quick response - but I''m not following you.

      I need the outer listview and would like each item to expand to show the inner listview - loading, I'm thinking, on the selectedIndexChanged event of the outer listview.

      What are you suggesting?

      Sylvia — January 18, 2011 1:15 PM
    17. Lee Dumond avatar

      If you use Ajax, you can have the client-side onclick event load only the data required for the inner listview, then show the inner list.

      If you try to do this on selectedIndexChanged, you will have to postback the entire form, which of course entails reloading the entire page and its associated data.

      Lee Dumond — January 18, 2011 1:26 PM
    18. Sylvia avatar

      Would you please explain this a little bit further?

      Would I use an update panel? how would I load the listview at the onclick event?

      Sylvia — January 18, 2011 1:35 PM
    19. Lee Dumond avatar

      There are probably 2 reasons your page is slow:

      1. You are loading all the data for the inner lists (even though they are hidden when the page loads)

      2. You aren't caching the data.

      The idea is to only load what the user needs to see when the page loads. Then, when the user clicks a row, only load the innerlist data associated with that one row, NOT the whole page.

      Check out Encosia.com -- he is the expert on doing Ajax with jQuery on ASP.NET.

      Lee Dumond — January 18, 2011 1:44 PM
    20. Sylvia avatar

      Thank you.

      I will check out Enocsia.com. I get WHY my page is loading slow - but just not how to fix it.

      Sylvia — January 18, 2011 1:54 PM
    21. Philip Hunt avatar

      Dear Lee

      I feel that your answer is what I have been looking for but I am still a little lost, and also want to do something just very slightly different to your example.

      To try to be as specific as possible: -

      1. Database structure I am working with, compared with your example -

      I have a publisher record with a key of Publisher ID and a few fields of data about each publisher (this would compare with your list of blog articles)

      I then have a series table, each record has a key of Series ID and each record also includes a Publisher ID as its foreign key (this would relate to your tags)

      A publisher may have one or more series linked to it, maximum currently = 6.

      2. Whereas you have placed your tags as a one line list under the article heading, or as a bulleted list below the heading, I want to place a row of images, as pointed at by a field in the Series records [the inner ListView], to the right of, and on the same line as, the data from the Publisher record [outer ListView].

      3. Though I have the books by your colleagues Imar and Bill, Scott and Devin I am still uncertain as to where I store the classes and methods, and, exactly what they look like, particularly the methods.

      In your article you have said

      [Quote]

      I've purposely left out the specific data access code from Figure 3.

      [/Quote]

      My problem is that is exactly where I am uncertain. My data is stored on an SQL Server 2008 R2 database, which I am accessing through use of LINQ to Entities. I have quite successfully coded the accessing of the Outer ListView data, but I am completely stuck as to how I incorporate the accessing of the Inner ListView data using classes and methods in the way you have described in your article.

      I should greatly appreciate your advice. I have a much more detailed version of this query prepared, including a Powerpoint story board mock-up of what I am trying to achieve, that I have posted on the Microsoft ASP forum at http://forums.asp.net/p/1637549/4230593.aspx#4230593?Display+a+variable+length+array+in+an+Entity+Data+Source+ListView, but I have received no replies that address my requirements in the way your entry here so closely does.

      Imar has been helping me greatly with other issues on the wrox p2p board, but as your entry here so closely addresses my need, I thought it was appropriate to pose my follow-ups here. If, on the other hand, you would wish me to post somewhere on wrox p2p, please just tell me where and, I will do it immediately (time differences allowing).

      I look forward to your reply.

      Best regards

      Philip Hunt

      Perth, Western Australia

      Philip Hunt — January 29, 2011 9:58 PM

    » Leave a Comment