How to bind DataTable of custom objects to GridView - c#

I have a list comprising of two other lists of custom objects that are linked by an Id. Essentially I have an 'CPDActivity' object that has many properties and an 'CPDActivityExtended' object with several more. I then have a 'CPDActivityComplete' object that contains one each of the other objects. These complete objects get added to a list which is what populates a DataTable.
I need to be able to bind this DataTable to a GridView and display the values of the properties of the CPDActivityComplete's two child objects. For example CPDActivityComplete.CPDActivity.A under an 'A' column.
Here is a basic picture of what I'm trying to do:
The list of custom objects visualised:
What I have tried so far:
The DataTables are populated using Entity Framework & LINQ and I have bound the GridView to the resulting DataTable:
DataTable dt = getCPDData.ToDataTable<CPDActivityComplete>(cpdActivityCompleteList);
cpd_gv_activities.DataSource = dt;
cpd_gv_activities.DataBind();
I have a simple GridView to test things out:
<asp:GridView ID="cpd_gv_activities" runat="server" AutoGenerateColumns="false" AllowPaging="True" PageSize="15">
<Columns>
<asp:TemplateField HeaderText="Full Name">
<ItemStyle CssClass="fixedcell"></ItemStyle>
<ItemTemplate>
<asp:Label ID="vd_gv_lbl_FullName" runat="server" Text='<%# Bind("CPDActivity.A") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
But this results in an error:
DataBinding: 'System.String' does not contain a property with the name 'A'.
How do I bind the label.text to CPDActivityExtended.CPDActivity.A property?

Switch to a strongly typed GridView. Then you have easy access to all the properties and type-safety.
So first add the ItemType to the GridView
<asp:GridView ID="cpd_gv_activities" runat="server" ItemType="YourNameSpace.CPDActivityComplete">
Now you can use Item in the GridView and access properties
<asp:Label ID="vd_gv_lbl_FullName" runat="server" Text='<%# Item.A %>'></asp:Label>
And last, don't convert to a DataTable (was not needed in the first place) but bind the List with the class directly.
cpd_gv_activities.DataSource = cpdActivityCompleteList;
cpd_gv_activities.DataBind();

Related

asp.net bind a list to a gridview

List<MasterBook> listOfBooks = new List<MasterBook>();
after i put the masterbook objects which by the way have 3 fields( name,id and active ) into the list
GridView1.DataSource = listOfBooks;
GridView1.DataBind();
in the web form
<Columns>
<asp:TemplateField HeaderText="Book Name">
<ItemTemplate>
<asp:Label ID="BookNameText" runat="server"
Text="<%#Container.DataItem%>">
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
the problem is that i want to display the bookmaster's name in the gridview column
this code print bookmaster in the column how can i make it type the name
Change:
<%#Container.DataItem%>
To:
<%#Eval("name")%>
Cast it to MasterBook:
Text="<%# ((MasterBook) Container.DataItem).Name %>">
The quick, dirty hack workaround is to overload the ToString() method of your MasterBookclass in order to return that name. Commit seppuku afterwards if you do it.
The elegant and graceful way is to make an object datasource. That way you can bind the grid view's columns to the objects' properties. In the case of a DataList or other templated data controls, you can bind your objects' properties to the data control's child controls in their templates.
The middle path is in hutchonoid's answer: evaluate a property of the object, not the object itself.
Use this sintax:
<asp:Label ID="BookNameText" runat="server"
Text="<%# ((MasterBook)Container.DataItem).Name %>">

Bind Literal control inside Gridview from codebehind.

I have a gridview which contains template fields in which every template field contains a litreal control, and I want to bind that grid view with my DataSet, please look into the code to find more.
Code to create DataSet-
DataTable Record = new DataTable();
Record.Columns.Add("zerker");
DataRow dr = Record.NewRow();
dr["zerker"] = "SomeText";
Record.Rows.Add(dr);
gvCustomres.DataSource = Record;
gvCustomres.DataBind();
Code to create GridView-
<asp:GridView ID="gvCustomres" runat="server" PageSize="4" AutoGenerateColumns="False" >
<Columns>
<asp:TemplateField HeaderText="Zerker">
<ItemTemplate>
<asp:Literal ID="zerkername" runat="server"></asp:Literal>
</ItemTemplate>
</asp:TemplateField>
</columns>
</asp:GridView>
Please help me to find correct way to do this.
Thanks,
Your code above is all right if you just want to bind Column "zerker" to your gridiview.
All you are missing is the Text Property for your Literal control.
<asp:Literal ID="zerkername" runat="server" Text='<%# Eval("zerker") %>'>
</asp:Literal>

C# ASP.NET List View

I am trying to create a view with multiple product listing in it. An example is below of how the product listing should look like. I am not sure if I should use a table and create a new table for each new product or what. I am not a very good ASP.NET developer and I am not sure how to approach this.
Basically if I have 10 results I need to display 10 of these in a list and each button and image is different based on each product result.
The source of data is from another class that was built and runs through a foreach for each product. Any guidance on this would be helpful. I just think I need to be pointed in the right direction because I tried it with a table and it wasn't working out to well.
Using GridView
<asp:GridView runat="server" ID="myGrid"
OnRowCommand="MyGrid_RowCommand">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<img src='<%# Eval("SmallImageUrl") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<div>Title: <%# Eval("Title") %> </div>
<div>Weight: <%# Eval("Weight") %> </div>
<asp:Button runat="server" ID="GetOfferButton" CommandArgument='<%# Eval("OfferID") %>'></asp:Button>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Assuming you have a collection of Products e.g. List, or DataTable of Product etc., and your collection has these fields
class Product
{
//property Title
//property SmallImageUrl
//property Weight
}
You can have
myGrid.DataSource = <Replace with List of Products collection>;
myGrid.DataBind();
Maybe you can try using asp.net table and just add rows with the images dynamically once you iterate your results..check out the control here:
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.table.aspx
and here you have an example to add rows dynamically:
http://msdn.microsoft.com/en-us/library/7bewx260%28v=vs.100%29.aspx
in each row you can put the controls that you want...

C# - Use same object for multiple columns in GridView

I have a student enrollment gridview populated with Enrollment objects. The Enrollment object has student Id. With that Id, I am populating 2 columns (from 3 properties of Student object) of enrollment gridview.
Right now, I am doing it with below code. This means 3 round trips to database for the same object, which is so very bad. How can I use the same object to get the 3 properties?
<asp:TemplateField HeaderText="Student Name">
<ItemTemplate>
<asp:Label ID="lblName" runat="server" Text='<%# string.Format("{0} - {1}", StudentProfile.GetStudentProfileById(Convert.ToInt32(Eval("StudentId"))).FirstName, StudentProfile.GetStudentProfileById(Convert.ToInt32(Eval("StudentId"))).Surname) %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Student DOB">
<ItemTemplate>
<asp:Label ID="lblDOB" runat="server" Text='<%# StudentProfile.GetStudentProfileById(Convert.ToInt32(Eval("StudentId"))).DateOfBirth %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
Edit: FYI, I have to deal with updating the gridview rows which will involve adding textboxes and so to each row. Can you please keep the answers apt to this point?
Thank you very much!
The way you are binding data to the gridview is wrong. You need to get the Data in an Object/Collection and then bind that data as a DataSource to your GridView.
Take a look here Displaying Data With the ObjectDataSource and look at this as well Querying Data with the SqlDataSource Control

Bind non-property to datagrid column DataField?

Let's say I have a DataGrid that looks something like:
<asp:DataGrid ID="SomeDataGrid" runat="server">
<Columns>
<asp:BoundColumn HeaderText="A Header" SortExpression="Sort" DataField="Data"></asp:BoundColumn>
</Columns>
</asp:DataGrid>
In this Grid, I set the datasource to some collection that contains a public property called "Data" and do a databind(). Every works as expected.
Now let's say I want to set the DataField attribute of the column to a public member, or a property, or some other thing I've computed. What is the easiest way to go about this without creating intermediate objects or adding public properties to the objects in the collection?
So what I want to do is something like:
<asp:BoundColumn HeaderText="A Header" SortExpression="Sort" DataField="someMethod()"></asp:BoundColumn>
Use a TemplateColumn
<asp:TemplateColumn HeaderText="Test">
<ItemTemplate>
<asp:Label runat="server" Text='<%# SomeMethod() %>'></asp:Label>
</ItemTemplate>
</asp:TemplateColumn>

Categories