Create table from a business object with conditional layout - asp.net

I need to generate a table from a List (Of Students). My Student class has properties for AcademicYear, TeachingSet, Surname and Forenames, is sorted in that order and also properties for ID and start date. The table should nest TeachingSets within AcademicYears and then the students within the TeachingSets, as shown in the table I've mocked up at http://www.ifslearning.ac.uk/files/student-table.jpg
Using a repeater I get
08-10 students B74394 Mzejb Bsppn
08-10 students B74395 Lbuifsjof Bvti
08-10 students C68924 Epoob Cmpblf
08-10 students D41468 Ipxbse Dbwfz
But I need to have
08-10 students
- B74394 Mzejb Bsppn
- B74395 Lbuifsjof Bvti
- C68924 Epoob Cmpblf
- D41468 Ipxbse Dbwfz

If you use asp .net Web Forms then you can look at ListView, DataList and Repeater controls. I would recommend you to try ListView. Here is a deep description about using this control. It is very simple to configure any layout you need:
<asp:ListView runat="server" ID="ListView1">
<LayoutTemplate>
<table>
<tr runat="server" ID="itemPlaceholder" />
</table>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td><%#Eval("YourObjectProp") %></td>
...
</td>
</ItemTemplate>
</asp:ListView>
You can group your objects like this:
List<AcademicYear> academicYears = new List<AcademicYear>();
var year = new AcademicYear { Year = "08-10" };
year.Students.Add(new Student { Name = "Mzejb Bsppn" });
year.Students.Add(new Student { Name = "Lbuifsjof Bvti" });
...
And layout:
<asp:ListView runat="server" ID="ListView1">
<LayoutTemplate>
<asp:PlaceHolder runat="server" ID="itemPlaceholder" />
</LayoutTemplate>
<ItemTemplate>
<%#Eval("Year") %> students<br />
<asp:ListView runat="server" ID="nestedListView" DataSource='<%# Eval("Students") %>'>
<LayoutTemplate>
<asp:PlaceHolder runat="server" ID="itemPlaceholder" />
</LayoutTemplate>
<ItemTemplate>
<%#Eval("Name") %><br />
</ItemTemplate>
</asp:ListView>
</ItemTemplate>
</asp:ListView>

Related

ListView.DataItem is showing null

Listview binding code
<asp:Content ID="Content3" ContentPlaceHolderID="leftColumnPlaceHolder" runat="server">
<asp:ListView ID="lvQuestions" runat="server" OnItemDataBound='lvQuestions_ItemDataBound'>
<LayoutTemplate>
<div id="itemPlaceholder" runat="server">
</div>
<asp:Button ID="btnSubmitAnswers" runat="server" Text="Submit Answers" OnClick="btnSubmitAnswers_Click" />
</LayoutTemplate>
<ItemTemplate>
<div>
<%# Container.DataItemIndex + 1 %>:<%# Eval("Body") %>
</div>
<asp:RadioButtonList ID="rdlAnswers" runat="server" DataSource='<%#Eval("ExamAnswer") %>' DataTextField='Body' DataValueField="AnswerId">
</asp:RadioButtonList>
</ItemTemplate>
</asp:ListView>
</asp:Content>
While fetching the listview items on submit button click..like below,
we are getting qsnItem.DataItem as NULL.
foreach (ListViewDataItem qsnItem in lvQuestions.Items)
{
}
Please suggest what is going wrong here.
The DataItem of all databound web-controls in ASP.NET are null on postbacks when you don't DataBind the control again, which is unnecessary when ViewState is enabled(default).
So you can use the controls in your templates to get the values:
foreach (ListViewDataItem qsnItem in lvQuestions.Items)
{
RadioButtonList rdlAnswers = (RadioButtonList)qsnItem.FindControl("rdlAnswers");
}
If you need to old values you need to load them from database or use the ListViewUpdatedEventArgs.OldValues Property.

ASP: Repeater not working

I've used this tutorial to use a repeater to display a list of names on a page on my project.
So I'm using dynamic data and in my aspx.cs page I have:
List<string> subContractors = new List<string>();
Context db = new Context();
subContractors = (from SUBContractors in db.BOQ_SubContractors
where SUBContractors.Bill_Of_Quantity_id == this.boqId
select SUBContractors.Sub_Contractor.Company_Name).ToList();
repeaterShowSubContractorName.DataSource = subContractors;
repeaterShowSubContractorName.DataBind();
In my aspx:
<asp:Repeater ID="repeaterShowSubContractorName" runat="server" OnItemDataBound="subContractors_ItemDataBound">
<HeaderTemplate>
<table>
<tr>
<th>
<asp:Label ID="SubConName" Text="SubContractor Name" runat="server"></asp:Label>
</th>
</tr>
</table>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<asp:Label ID="SubCon" Text='<%# Eval("subContractors") %>' runat="server"></asp:Label>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
The error is coming from OnItemDataBound="subContractors_ItemDataBound".
What or where do I link this to? I have no subContractors_ItemDataBound at the moment.
just remove OnItemDataBound="subContractors_ItemDataBound" from your aspx page
Edit this error occurred because you don't have subContractors_ItemDataBound method in .cs file to handle OnItemDataBound event , so you have to handle OnItemDataBound event or just remove OnItemDataBound="subContractors_ItemDataBound"
Edit to bind list of strings use :
<asp:Label ID="SubCon" Text='<%# Container.DataItem %>' runat="server"></asp:Label>
Do this on your page load (or wherever you want to laod data) to link your data with repeater
repeaterShowSubContractorName.DataSource = subContractors;
repeaterShowSubContractorName.DataBind();
and remove
OnItemDataBound="subContractors_ItemDataBound"

Binding Repeater with Dictionary<string, Dictionary<int,[object]>

I am new to .NET, so I'm struggling with this. I have a content page, with a repeater control. I have a Dictionary, which is a Dictionary<string, Dictionary<int,[object]>>. I want the value of the controls inside the repeater control to get it from the object attributes - Candidate Name, would be object.CandName, candidate phone would be object.Phone etc.
I am not sure how to use Eval for this type of Dictionary. Most of the examples point to Eval("Value"), but it is not giving the correct value for me. Kindly help!
<asp:Content ID="Content2" ContentPlaceHolderID="content" Runat="Server">
<div id="rcontent">
<table>
<tr>
<td>
<asp:Label ID="lblerror" runat="server" Text="" Visible="true" CssClass="alert"></asp:Label>
</td>
</tr>
</table>
<div id ="rptdiv">
<asp:Repeater ID="Repeater1" runat="server" EnableViewState="false">
<ItemTemplate>
<div id="Div3">
<table class="GridViewStyleNoBorder" width=750px cellspacing="0" border="0" >
<tr>
<td class="PagerStyle" colspan="4">
<asp:Label ID="lblName" Runat="server"
Text='<%= Need the value of the [object].objectproperty from dictionary here %>' />
</td>
</tr>
</table>
</div>
This is my Page_Load code behind - BLDecision is my business layer code, which returns the dictionary and dictionary values are correct. I checked them in debug mode.
Code Behind:
Dictionary(int, Dictionary(int, InterviewFeedback)) ;
CandIntDetails = new Dictionary(int, Dictionary(int, InterviewFeedback))();
BLDecision objBLDecision = new BLDecision();
int ReqCategoryID = 0;
if (Request.QueryString["ReqCategoryID"] != null)
ReqCategoryID = int.Parse(Request.QueryString["ReqCategoryID"].ToString());
CandIntDetails = objBLDecision.GetCandidatesforReqCategory(ReqCategoryID);
Repeater1.DataSource = CandIntDetails;
Repeater1.DataBind();
Should I use from codebehind, can I not do Eval('<% ....%>') in the aspx page?
Thanks in advance for your help.
You cannot do it with only one repeater. Since you have a container inside a container, you need a Repeater inside a repeater:
<asp:Repeater ID="Repeater1" runat="server" EnableViewState="false">
<ItemTemplate>
<div id="Div3">
<table class="GridViewStyleNoBorder" width=750px cellspacing="0" border="0" >
<asp:Repeater ID="Repeater2" runat="server" DataSource='<%# Eval("Value")' >
<ItemTemplate>
<tr>
<td class="PagerStyle" colspan="4">
<asp:Label ID="lblName" Runat="server"
Text='<%# Eval("Name") %>' />
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
</table>
</div>
</ItemTemplate>
</asp:Repeater>
If CandIntDetails is a Dictionary<int, Dictionary<int, InterviewFeedback>>, you need to extract from that the specific collection you want to use as the data source of your repeater. The reason why is because you want to render a collection of InterviewFeedback objects, which CandIntDetails is not. CandIntDetails probably looks something like this:
{
46: {
0: [InterviewFeedback],
1: [InterviewFeedback],
2: [InterviewFeedback]
}
}
It's not clear from your post what the keys are for the inner or outer dictionaries, so this is speculative. If the outer key is the the category ID (not sure why GetCandidatesforReqCategory would return something like that), and if you don't care about the inner dictionary keys, you can extract your data source like this:
Repeater1.DataSource = CandIntDetails[ReqCategoryID].Values;
That will make your data source a straight collection of InterviewFeedback objects. Once that's your data source, you can Eval to access the properties of the InterviewFeedback objects.

How to use GetIndexedPropertyValue?

I have the following ListView:
<asp:ListView ID="lv_Announcements" runat="server">
<LayoutTemplate>
<asp:PlaceHolder ID="itemPlaceHolder" runat="server" />
</LayoutTemplate>
<ItemTemplate>
<%# Eval("Title") %><br />
<%# DataBinder.GetIndexedPropertyValue(Fields, "[\"Body\"]")%><br /><br />
</ItemTemplate>
</asp:ListView>
In my code behind I am doing this:
lv_Announcements.DataSource = cur.Web.Lists["Announcements"].Items;
lv_Announcements.DataBind();
Where Items is a SPListItemCollection. When ever I run my code I get the following error:
The name 'Fields' does not exist in
the current context
Should I be doing something differently here?
I ended up doing it like this:
<%# DataBinder.GetIndexedPropertyValue(Container.DataItem, "[\"Body\"]")%>
DataItem is the SPListItem that the row is being bound to so you can think of it like this:
SPListItem myItem = //whatever;
myItem["Body"];
Before it would have been like this:
SPListItem myItem = //whatever;
myItem.Fields["Body"];
Which does not return the information I wanted.

how to update label value of gridview with another value

I have gridview with ajax rating control where i am updating rating value on change event and i am saving that data into the database using sql datasource and i want to show that change value into another label .But when i am updating the value it makes change in database but not in the label. please tell me how can i change lbel value at that same time i am using these code.
<asp:GridView ID="GVTweet" runat="server" AllowSorting="True" DataKeyNames="id" AllowPaging="true"
AutoGenerateColumns="False" GridLines="Horizontal" PageSize="15" Width="700px"
onselectedindexchanged="GVTweet_SelectedIndexChanged"
onrowcancelingedit="GVTweet_RowCancelingEdit"
onrowediting="GVTweet_RowEditing"
onrowupdated="GVTweet_RowUpdated" onrowupdating="GVTweet_RowUpdating"
DataSourceID="SqlDataSource2"
onpageindexchanging="GVTweet_PageIndexChanging" >
<HeaderStyle />
<Columns>
<asp:TemplateField HeaderImageUrl="~/images/rate1.png"
HeaderStyle-CssClass="headerCss1" HeaderText="Rate(1-5)"
SortExpression="Rating" >
<ItemTemplate>
<table border="0" cellpadding="0" cellspacing="0" width="auto">
<tr style="width:150px;" valign="top" >
<td style="height:30px;">
<asp:Label ID="lblTotalRate" runat="server"
Text='<%#DataBinder.Eval(Container.DataItem, "TotalRate")%>'></asp:Label>
</td>
</tr>
<tr style="width:150px;" valign="top" >
<td style="height:30px;">
<asp:UpdatePanel ID="updtpnlTweet" runat="server">
<ContentTemplate>
<cc1:Rating ID="rateTweet" runat="server" CurrentRating='<%# Bind("Rating") %>'
EmptyStarCssClass="empatyStarRating" FilledStarCssClass="filledStarRating"
MaxRating="5" onchanged="rateTweet_Changed" StarCssClass="ratingStar"
WaitingStarCssClass="savedStarRating">
</cc1:Rating>
</ContentTemplate>
</asp:UpdatePanel>
</td>
</tr>
</table>
</ItemTemplate>
<HeaderStyle CssClass="headerCss1" />
</asp:TemplateField>
this is html that i using and i want that rating value after updation in this label lblTotalRate.
protected void rateTweet_Changed(object sender, AjaxControlToolkit.RatingEventArgs e)
{
try
{
// cast rating control which has initiated the call:
AjaxControlToolkit.Rating myRating = (AjaxControlToolkit.Rating)sender;
// regular expression which will help identifying row number:
System.Text.RegularExpressions.Regex rexLineNo = new System.Text.RegularExpressions.Regex("ctl\\d+");
// update the record based on the recodrd id
this.updateRating(this.ProductId(rexLineNo.Match(myRating.UniqueID).ToString()), e.Value);
// the above line does the following:
// rexLineNo.Match(myRating.UniqueID).ToString() - finds "ctl and line number
//GVTweet.DataSourceID = "SqlDataSource2";
// GVTweet.DataBind();
GVTweet_RowUpdated( sender2, e2);
// this.Page.Form.Action = "AddRating()";
// SqlDataSource2_Updated(sender1, e1);
}
catch
{
}
}
If any buddy has please tell me .javascript and both is ok for me.
This is code behind code
enter code here
Seems that a piece of code is missing...
anyway, as far as I can see from the code, the label is not into an UpdatePanel. If the expected behavior is to change asynchronously both of the controls you have to manage a partial update in the Label too, or trigger a complete page postback (which is not probably what you want).

Resources