C# - Use same object for multiple columns in GridView - c#

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

Related

How to bind DataTable of custom objects to GridView

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();

Grid View Format By Row

I'm wondering if it is possible to format a Grid View like the pattern below
Usual Grid View:
Name Address Age Gender <--- Fields Name
Example Example Example Example <--- Values
What I want to look like
"Fields" "Values"
Name Example
Address Example
Age Example
Gender Example
Any thought will be highly appreciated
you should look into using a repeater.
I think that GridView was simply not meant to be used that way. Usually, you will display several items in it and if those items are too many you will end up with the horizontal scrolling mistake (also, some nice arguments here).
If you are showing only one record, you should use a DetailsView control, which:
Displays the values of a single record from a data source in a table,
where each data row represents a field of the record. The DetailsView
control allows you to edit, delete, and insert records.
I got an Answer using this Codes:
<asp:GridView ID="GridView1" runat="server" DataSourceID="SqlDataSource1" AutoGenerateColumns="False" >
<Columns>
<asp:TemplateField HeaderText="">
<ItemTemplate>
Name: <asp:Label ID="Label1" runat="server" Text='<%# Eval("Name") %>'></asp:Label><br />
Address: <asp:Label ID="Label2" runat="server" Text='<%# Eval("Address") %>'></asp:Label><br />
Postcode: <asp:Label ID="Label3" runat="server" Text='<%# Eval("Postcode") %>'></asp:Label><br />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>

Multiple Column Dropdown in Details View control

I have created a dropdown list in a DetailsView control
I want to make that dropdown have multiple columns. Is that possible? If So how?
I've done a lot of searching and cant seem to find the solution.
Below is the code for my dropdown template:
<asp:TemplateField HeaderText="Division" SortExpression="fDivisionID">
<EditItemTemplate>
<asp:DropDownList
ID="DivisionDropDownList"
runat="server"
DataSourceID="DivisionSqlDataSource"
DataTextField="DivisionName"
DataValueField="DivisionID"
Text='<%# Bind("fDivisionID") %>'>
</asp:DropDownList>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Bind("DivisionName") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
How do I add another column to that.. such as "Location"..
Thanks in advance
There are I think three ways actually.
Add two columns in your Select statement when fetching from database like below. or from here
Select Column1 + ' ' + Column2 From Yourtable
You can use third party controls.
Jquery Also supports this feature Here

GridView trouble in .Net

i think this maybe an easy one...
I have a Gridview, bound to a dataSource with this query:
select userid, name, phone from users
I need to change the content of the Name cell to a link, like so:
User's Name
so OnRowDataBound i'm doing this:
e.Row.Cells[1].Text = "" + e.Row.Cells[1].Text + "";
It all works fine this way. My problem is that i don't want to display the UserId column in the Gridview, but when i attribute it (asp attribute or server-side) Visible="false" to the BoundField UserId, i can't capture it's value to build the Name Cell.
Thanx for your help
Make your gridView to use template items instead of simple grivdiew column.
<asp:TemplateField HeaderText="FirstName" SortExpression="FirstName">
<EditItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("FirstName")%>'>
</asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Bind("FirstName") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
You can find a nice intro Here
Agree with Jani, this should be done with a template field. If you really need to do it the other way, see Can data be kept in a dynamically bound GridView's invisible fields?.
you can set the visibility on the onrowdatabound event

How do i put 2 DataSet Table Results in one GridView Column?

I have two results from a data set. I want to add both results in one gridview column. I do not want to merge in the code behind. Is there another way to do that?
<asp:TemplateField HeaderText="Entered Date" SortExpression="Date">
<ItemTemplate>
<div style="text-align: center;">
<asp:Label ID="Label3" runat="server" Text='<%# formatDisplayDate(Eval("Date").ToString()) %>'></asp:Label>
</div>
</ItemTemplate>
</asp:TemplateField>
Now i would return "04/04/2009". I would like to return "04/04/2009-PASSED"
Have you tried:
formatDisplayDate(Eval("Date").ToString()) & "-" & Eval("OtherField").ToString()
If that doesn't work you should be able to set up a TemplateField for the combined rows like this:
<asp:TemplateField HeaderText="CombinedFieldName" SortExpression="CombinedFieldName">
<ItemTemplate>
<asp:Label ID="Label1" runat="server"
Text='<%# DataBinder.Eval(Container,"DataItem.FirstField") %>' >
</asp:Label>
-
<asp:Label ID="Label2" runat="server"
Text='<%# DataBinder.Eval(Container,"DataItem.SecondField") %>' >
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
That said - it is usually much more efficient to do the field concatenation in the database operation if possible. I haven't tested, but I would assume that concatenating in the SELECT would be fastest, followed by concatenating in the data set in the codebehind, and combining them on the ASP.Net page would be slowest.
Another option would be to create a calculated column in the DataTable, using the DataColumn.Expression property
My first question is why don't you want to merge in the code behind? The more content you bind to a control the more data that gets put into that controls view state.
#Gary.Ray has a really good solution, but something you might find better is to use linq to build a single data object from your existing data sets that way you only include what you need and the data is a lot easier to isolate, think single responsibility pattern here, if you can move the code that deals with getting your data to somewhere that only deals with getting data your application will be MUCH easy to maintain in the future.

Categories