Binding List of Custom Class to GridView or ListView Control

Scenario:

I am not going to write a lot but just show some code. Say you have a class(e.g. Customer) that itself exposes another class(e.g.Person) as its property. Now you want to take a List of Customer class and bind it to databound controls like GridView Or ListView ?

 public class Customer
{
    public Customer()
    {
        this.CustPerson = new Person();
    }
    public int id { get; set; }
    public Person CustPerson { get; set; }
}

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }
}

Binding it to GridView:

Here is code that populates GridView with list of customers:

  List<Customer> customerlist = new List<Customer>();

        for (int i = 0; i <= 4; i++)
        {
            Customer cust = new Customer();
            cust.id = i;
            cust.CustPerson.FirstName = "John-" + i.ToString();
            cust.CustPerson.LastName = "Doe-" + i.ToString();
            cust.CustPerson.Age = 20 + i;
            customerlist.Add(cust);
        }

        GridView1.DataSource = customerlist;
        GridView1.DataBind();

Problem:

But say if your GridView is set to AutoGenerateColumns=true, which is default, then GV will show only the "id" column and the columns pertaining to Person are kind of lost.

GV with properties missing

How to access that inner class (e.g. Person here) ?

Answer to that is you need to explicitly cast the DataItem.Below is sample how you will display FirstName.

 <asp:TemplateField HeaderText="FirstName">
                     <ItemTemplate>
                        <asp:Label ID="Label2" runat="server" Text='<%# ((Customer)Container.DataItem).CustPerson.FirstName %>'></asp:Label>
                    </ItemTemplate>
 </asp:TemplateField>

Similarly adding other columns the view will be something like below.

 

To get reference to DataItem in code-behind:

 protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if(e.Row.RowType== DataControlRowType.DataRow)
        {
            Customer drv = (Customer)e.Row.DataItem;

        }
    }

Conclusion:

Same concept goes with other databound controls like ListView. Hope it helps and let me know if you have any questions. 

15 Comments

  • Really good, people like me who are new to developing an item for an webpage. &nbsp;

    I am working on a page starting with creating the user table. &nbsp;Now, question is how I can store the user profile information that user submits to the SQL SERVER 2008 table. &nbsp;I will really appreciate your help.

    Thank You.

  • Fouzia,
    Are you using your own database schema or default asp.net membership schema?
    Check this: http://weblogs.asp.net/gurusarkar/archive/2009/01/27/storing-user-profile-into-a-custom-table-using-createuser-wizard-control.aspx
    If that's not what you are looking for please provide more information.
    Can you share more details.

    Alternatively, you can post your question here: http://forums.asp.net/25.aspx and post the link to your thread here and I will take a look.

  • I am attempting to bind a BindingList to a GridView. Like your sample, the BindingList is of a custom object called "Person". First, I allow the user to add records to the GridView using page TextBoxes and clicking a button. This works fine; the code is very similar to your add code. However, I am having trouble getting the grid to allow editing and removing records. I have set the BindingList "AllowEdit" and "AllowRemove" properties, but it seems that all of the events and everything involved must be handled manually in the code behind. Do you know of a simpler way to accomplish this? I have attempted using an ObjectDataSource because I read that it simplifies the editing and deleting, but my lack of familiarity with it caused me more problems than attempting it manually. If you could inform me of how to allow editing and deleting or provide another sample (whether a link or something similar to your code above), I would be very appreciative. Thanks.

  • Joshua,
    ---->Do you know of a simpler way to accomplish this?
    I haven't played with BindingList much so I don't have anything useful for you.
    If I get a chance I will look into it and see if I can update this post.

    But for your trouble with ObjectDataSource check out some tutorials here that uses ODS:
    http://www.asp.net/web-forms/data

  • Hi,

    I did the same example but its giving an error

    CS0246: The type or namespace name 'Customer' could not be found (are you missing a using directive or an assembly reference?)

    To solve this problem..

    in .aspx file

    &nbsp; &nbsp; &nbsp; &nbsp;&lt;asp:GridView ID="GridView1" runat="server" &gt;

    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;Columns&gt;

    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;asp:TemplateField HeaderText="FirstName"&gt;

    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;ItemTemplate&gt;

    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;asp:Label ID="Label2" runat="server" Text='&lt;%# DataBinder.Eval(Container,"DataItem.CustPerson.FirstName") %&gt;'&gt;&lt;/asp:Label&gt;

    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;/ItemTemplate&gt;

    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;/asp:TemplateField&gt;

    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;/Columns&gt;

    &nbsp; &nbsp; &nbsp; &nbsp;&lt;/asp:GridView&gt;

    in code behind file..

    namespace WebApplication1

    {

    &nbsp; &nbsp;public class Customer

    &nbsp; &nbsp;{

    &nbsp; &nbsp; &nbsp; &nbsp;public Customer()

    &nbsp; &nbsp; &nbsp; &nbsp;{

    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;this.CustPerson = new Person();

    &nbsp; &nbsp; &nbsp; &nbsp;}

    &nbsp; &nbsp; &nbsp; &nbsp;public int id { get; set; }

    &nbsp; &nbsp; &nbsp; &nbsp;public Person CustPerson { get; set; }

    &nbsp; &nbsp;}

    &nbsp; &nbsp;public class Person

    &nbsp; &nbsp;{

    &nbsp; &nbsp; &nbsp; &nbsp;public string FirstName { get; set; }

    &nbsp; &nbsp; &nbsp; &nbsp;public string LastName { get; set; }

    &nbsp; &nbsp; &nbsp; &nbsp;public int Age { get; set; }

    &nbsp; &nbsp;}

    &nbsp; &nbsp;public partial class WebForm2 : System.Web.UI.Page

    &nbsp; &nbsp;{

    &nbsp; &nbsp; &nbsp; &nbsp;protected void Page_Load(object sender, EventArgs e)

    &nbsp; &nbsp; &nbsp; &nbsp;{

    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;List&lt;Customer&gt; customerlist = new List&lt;Customer&gt;();

    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;for (int i = 0; i &lt;= 4; i++)

    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{

    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Customer cust = new Customer();

    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cust.id = i;

    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cust.CustPerson.FirstName = "John-" + i.ToString();

    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cust.CustPerson.LastName = "Doe-" + i.ToString();

    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cust.CustPerson.Age = 20 + i;

    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;customerlist.Add(cust);

    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}

    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;GridView1.DataSource = customerlist;

    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;GridView1.DataBind();

    &nbsp; &nbsp; &nbsp; &nbsp;}

    &nbsp; &nbsp;}

    }

    because mostly we don't maintain user defined classes in side

    "public partial class WebForm2 : System.Web.UI.Page"

    you did really nice job...

    Thank you...

  • Thanks Aravind Kumar for clarification.
    Yes, usually we don't include classes inside Page's code-behind. So you have to add reference to assembly and namespace depending on where you define your class.
    But for this case my classes were not inside a namespace and the class files are inside App_Code folder and so it works without any error.

  • Thanks for the hint !

    Is there a book / MSDN article that explains this in greater detail, ie biding a generic list with a data control ? I found that if I set my gridview autoGenerateColumns property to TRUE that my data was displayed.

  • GMann,
    I don't know where I exactly got this from but here is a basic GV Databinding article if that helps: http://highoncoding.com/Articles/206_GridView_DataBinding.aspx
    If your GV displays data with AutoGenerateColumns=true, may be your class isn't having any property of a custom type.
    Or I am completely misunderstanding your question.

  • Can we use the same concept for BoundField with some tweaking rather than TemplateFields?

  • @Raj:
    No, not in .aspx markup. You will have to do that in code behind / RowDataBound event and set value by e.Row.Cells[i].Text = some value...

  • is there a way to accomplish this from the c# code in some event? i'm trying to bind a custom class to a grid view which is in a web control in a separate dll

  • radu,
    Not getting your questuon right but check the RowDataBound event in the last code block above.

  • Error 17 The type or namespace name 'Listdatabind' could not be found (are you missing a using directive or an assembly reference?) D:\3Z\3Z\AddRole.aspx.cs 22 5 D:\3Z\3Z\

  • @sivaguru,
    What is Listdatabind in your code? Can you share your code?

  • suppose i don't know the no of columns in my gridview it could be 5,10 or even 50 and i set autogeneratecolumns property to true then , can i use these getter setter method of the person class in the above example.

Comments have been disabled for this content.