bind data to repeater inside a gridview - c#

Hi have a repeater which is inside a gridview. when i bind the data to gridview the data is binding to the controles inside the gridview but repeater is not binding.
<asp:GridView ID="gvMain" runat="server" AllowPaging="false" AutoGenerateColumns="false"
Width="200px" Height="200px"
onrowdatabound="gvMain_RowDataBound">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="lbtnDptName" runat="server" Text='<%# Eval("deptName")%>'></asp:LinkButton>
<asp:Label ID="lblDptDesc" runat="server" Text = "sdfsdfsdfdsf"></asp:Label>
<asp:Repeater ID="rtFunctions" runat="server" OnItemDataBound="rtFunctions_ItemDataBound" >
<HeaderTemplate>
<table>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<asp:LinkButton ID="lbtnFunctions" runat="server" ></asp:LinkButton>
<asp:Label ID="lbltemp" Style="border:1px solid blue;width:20px;height:20px;background:green" runat="server" Text="TempLabel" ></asp:Label>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
in Page load:
gvMain.DataSource = objDeptColl;
gvMain.DataBind();
Codebehind for repeater:
protected void gvMain_RowDataBound(object sender, GridViewRowEventArgs e)
{
FunctionCollection objTempFuncColl = new FunctionCollection();
objTempFuncColl = (FunctionCollection)Cache["objFuncColl"];
Repeater rt = (Repeater)e.Row.FindControl("rtFunctions");
if (e.Row.RowType == DataControlRowType.DataRow && objTempFuncColl.Count !=0 )
{
rt.DataSource = objTempFuncColl;
rt.DataBind();
}
}
protected void rtFunctions_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
FunctionCollection objTempFuncColl = new FunctionCollection();
objTempFuncColl = (FunctionCollection)Cache["objFuncColl"];
Repeater rt = (Repeater)e.Item.FindControl("rtFunctions");
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
foreach (Functions f in objTempFuncColl)
{
LinkButton lnk = (LinkButton)e.Item.FindControl("lbtnFunctions");
lnk.Text = f.funcName;
}
}
}
linkbutton in gridview is binding but the linkbutton in repeater is not binding.

The problem appears to be with your repeater ondatabound function.
FunctionCollection objTempFuncColl = new FunctionCollection();
objTempFuncColl = (FunctionCollection)Cache["objFuncColl"];
The first line is not needed as you then replace it with the contents of the cache, which might be null if it's expired or purged or an instance.
For each row in your repeater, the link will be set to the last value in the objtempfunccoll.
you don't really need any of the function apart from lnk.Text = f.funcName; (you'll need to cast f from dataitem)
When you databind to the gridview, ondatabound is called for each row. you've got that wired-up. For each row you now need to find the repeater, set its datasource (we'll call this inner collection) & call databind on the repeater. this will cause ondatabound on the repeater to be called but the container.dataitem now points to each item in the inner collection. We can use that directly, casting container.dataitem to whatever type the inner collection is a list of.
protected void gvMain_RowDataBound(object sender, GridViewRowEventArgs e)
{
FunctionCollection objTempFuncColl = (FunctionCollection)Cache["objFuncColl"];
Repeater rt = (Repeater)e.Row.FindControl("rtFunctions");
if (e.Row.RowType == DataControlRowType.DataRow && objTempFuncColl.Count !=0 )
{
rt.DataSource = objTempFuncColl;
rt.DataBind();
}
}
protected void rtFunctions_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
lnk.Text = ((Functions)e.Item.DataItem).funcName;
}
Simon

You do not appear to be binding the repeater within any of this code. You may have some code to bind data to the GridView control, but this will not automatically bind anything to the repeater within the ItemTemplate.

Why don't databind in the aspx, leaving empty the code behind:
<asp:GridView ID="gvMain" runat="server" AllowPaging="false" AutoGenerateColumns="false"
Width="200px" Height="200px">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="lbtnDptName" runat="server" Text='<%# Eval("deptName")%>'></asp:LinkButton>
<asp:Label ID="lblDptDesc" runat="server" Text = "sdfsdfsdfdsf"></asp:Label>
<asp:Repeater ID="rtFunctions" runat="server" DataSource='<%# Cache["objFuncColl"] %>' >
<HeaderTemplate>
<table>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<asp:LinkButton ID="lbtnFunctions" runat="server" Text='<%# Eval("funcName") %>' ></asp:LinkButton>
<asp:Label ID="lbltemp" Style="border:1px solid blue;width:20px;height:20px;background:green" runat="server" Text="TempLabel" ></asp:Label>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>

Related

How to work with DataBinder.Eval in GridView?

I have a GridView contains Lables, I need to show/hide Lables based on data.
Here is my GridView:
<asp:GridView ID="GridView_Profiles" runat="server" CssClass="grid" HorizontalAlign="Center"
OnRowDataBound="GridView_Profiles_OnRowDataBound" CellSpacing="1" GridLines="None"
AutoGenerateColumns="False" Width="90%">
<Columns>
<asp:Label ID="Label_SelectedCount" runat="server">
<span style="width:auto;color:White;background-color:#0c95be;height:auto;margin:0px;font-size:12px;cursor:pointer;padding-left:10px;padding-right:10px;padding-top:5px;padding-bottom:5px;">
<%#Eval("Count") %>
</span>
</asp:Label>
<asp:Label ID="lblNoCount" runat="server" Text="-"></asp:Label>
</Columns>
</asp:GridView>
In the above GridView RowDataBound how should I check for the bounding data using DataBinder.Eval?
Use this to get Label in RowDataBound event with DataBinder.Eval:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// find your label text in gridview with DataBinder.Eval
string count = DataBinder.Eval(e.Row.DataItem, "Count") as string;
// find your label control in gridview
Label lb = (Label)e.Row.FindControl("Label_SelectedCount");
// check condition to show/hide label (you use your own condition)
if(count > 0)
lb.Visible = true;
else
lb.Visible = false;
}
}
Or you can bind GridView with DataBinder.Eval like:
<asp:TemplateField HeaderText="Count"
<ItemTemplate>
<asp:Label ID="Label_SelectedCount" runat="server" >
<%# DataBinder.Eval(Container.DataItem, "Count")%>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
Note: You can also bind data to Label's Text attribute like this Text='<%#Eval("Count") %>'.

page load with child grids taking too much of time in loading the page

I have three grids - Category grid, Items grid and Sub Items Grid. I have category grid (grdCategories) and for each category there are many items which i bind to child grids (grdItems). For every item there are many sub items which i display in sub child grid (grdSubItems). Now the problem is that page takes too much of time in loading the data. My HTML Code is below:
It takes even minutes to load the data:
ASPX
<asp:GridView ID="grdCategories" runat="server" AutoGenerateColumns="false" DataKeyNames="Category"
CssClass="menu_items" OnRowDataBound="grdCategories_RowDataBound">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Panel ID="pnlMealOptionsHeader" runat="server" Width="100%">
<h1>
<a id='<%# Eval("CategoryX")%>'>
<asp:Label ID="lblCategory" runat="server" Text='<%#Eval("Category") %>' Visible="false"></asp:Label>
<asp:Label ID="lblCategoryX" runat="server" Text='<%#Eval("CategoryX") %>'></asp:Label>
</a>
</h1>
</asp:Panel>
<asp:Panel runat="server" ID="pnlMealOptionsBody">
<asp:Label ID="lblCategoryXX" runat="server" CssClass="title_2" Text='<%#Eval("CategoryXX") %>'></asp:Label>
<!--Items in Category -->
<asp:GridView ID="grdItems" runat="server" AutoGenerateColumns="false" CssClass="active-grid"
DataKeyNames="Item" OnRowDataBound="grdItems_RowDataBound" ShowHeader="false" >
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="lblItem" runat="server" Text='<%#Eval("Item") %>' Visible="false"></asp:Label>
<asp:Label ID="lblItemX" CssClass="title" runat="server" Text='<%#Eval("ItemX") %>'></asp:Label>
<asp:Label ID="lblItemXX" CssClass="title" runat="server" Text='<%#Eval("ItemXX") %>' style=" font-size:smaller; font-weight:normal"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:GridView ID="grdSubItems" runat="server" AutoGenerateColumns="false" CssClass=""
DataKeyNames="SubItem" ShowHeader="false" OnRowDataBound="grdSubItems_RowDataBound">
<HeaderStyle HorizontalAlign="Left" />
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="lblItem" runat="server" Text='<%#Eval("Item") %>' Visible="false"></asp:Label>
<asp:Label ID="lblSubItem" runat="server" Text='<%#Eval("SubItem") %>' Visible="false"></asp:Label>
<asp:Label ID="lblNoofOptions" runat="server" Text='<%#Eval("NumofOptions") %>' Visible="false"></asp:Label>
<asp:Label ID="lblSubItemX" CssClass="qty" runat="server" Text='<%#Eval("SubItemX") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="lblPrice" runat="server" CssClass="price" Text='<%#String.Format("£{0}",Eval("SellingCost")) %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<!--End Items in Category -->
</asp:Panel>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<EmptyDataTemplate>
<table width="900px">
<tr>
<td align="center">
<h1>
No Data Available</h1>
</td>
</tr>
</table>
</EmptyDataTemplate>
</asp:GridView>
Code Behind
Categories Gridview Bind
private void FillCategoriesGrid()
{
DataSet ds = new DataSet();
ShopCategoryMapBL bl = new ShopCategoryMapBL(SessionContext.SystemUser);
bl.FetchForShop(ds, RowId);
grdCategories.DataSource = ds.Tables[0].DefaultView;
grdCategories.DataBind();
}
Items Gridview Bind
protected void grdCategories_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
GridView chkTopings = e.Row.FindControl("grdItems") as GridView;
Label lblCategory = e.Row.FindControl("lblCategory") as Label;
FillItemsGrid(chkTopings, WebHelper.Cast(lblCategory.Text, 0));
}
}
protected void FillItemsGrid(GridView grdItems, int Category)
{
try
{
//int cleanOrder = CargoBag.GetValue("CleanOrder", 0);
DataSet aDataSet = new DataSet();
ItemBL bl = new ItemBL(SessionContext.SystemUser);
bl.FetchForCategory(aDataSet, Category, RowId);
grdItems.DataSource = aDataSet.Tables[0];
grdItems.DataBind();
}
catch (Exception ex) { }
}
Sub Items Gridview Bind
protected void grdItems_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
GridView grdSubItems = e.Row.FindControl("grdSubItems") as GridView;
Label lblItem = e.Row.FindControl("lblItem") as Label;
FillSubItemsGrid(grdSubItems, WebHelper.Cast(lblItem.Text, 0));
}
}
protected void FillSubItemsGrid(GridView grdSubItems, int Item)
{
try
{
//int cleanOrder = CargoBag.GetValue("CleanOrder", 0);
DataSet aDataSet = new DataSet();
SubItemBL bl = new SubItemBL(SessionContext.SystemUser);
bl.FetchForItem(aDataSet, Item);
grdSubItems.DataSource = aDataSet.Tables[0];
grdSubItems.DataBind();
}
catch (Exception ex) { }
}
You need to provide all of your code before we can provide an accurate answer.
For example:
Where SubItemBL is defined?
Also try to see what line is the exact bottleneck.
Is it
bl.FetchForCategory(aDataSet, Category, RowId);
or
grdSubItems.DataBind();
If above line is the bottleneck, note that Gridview binding to a datasource with large number of data is indeedslow. how large is your data?

How to reference a linkbutton thats inside a asp:grid when its clicked

I have a ASP:grid which has a link button, i need to some how reference that on the code behind when its clicked but im struggling on the syntax
Heres my ASP:Grid i need to execute code in the code behind when that link button 'Re-Take' is pressed and also be able to know what row it was clicked on as i will need to reference the users emails and name and then send an email with the relevant information....
<asp:GridView ID="GrdViewUsers" runat="server" AutoGenerateColumns="false" GridLines="None"
EnableViewState="false" class="tablesorter">
<AlternatingRowStyle></AlternatingRowStyle>
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton Text="Re-Take" runat="server" ID="Edit" CommandName="Edit"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Full Name">
<ItemTemplate>
<asp:HyperLink ID="HyperFullName" CssClass="gvItem" runat="server" NavigateUrl='<%#Eval("UserID","/ExamPaper.aspx?uid={0}") %>'
Text='<%# DataBinder.Eval(Container,"DataItem.FullName") %>'></asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Email">
<ItemTemplate>
<asp:Label ID="lblSurname" CssClass="gvItem" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.Email") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Exam Taken">
<ItemTemplate>
<asp:Label ID="lblUsername" CssClass="gvItem" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.ExamTaken") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Date Taken">
<ItemTemplate>
<asp:Label ID="lblUsername" CssClass="gvItem" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.DateTaken") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Exam Total">
<ItemTemplate>
<asp:Label ID="lblUsername" CssClass="gvItem" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.ExamTotal") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
If someone can help me with a snippet i would highly appreciate it
You could approach this slightly different. You see, when a control is placed inside a gridview, any event raised from that control raises also the RowCommand on the GridView.
To get what you want you could then add both CommandName and CommandArgument to your LinkButton and then catch it in the GridView's RowCommand.
<asp:LinkButton id="LinkButton1" runat="server" commandName="LinkButtonClicked" commandArgument='Eval("myObjectID")' />
where myObjectID is the name of the ID column of your object you bind the grid to.
Then
void GridView1_RowCommand( object sender, GridViewCommandEventArgs e )
{
if ( e.CommandName == "LinkButtonClicked" )
{
string id = e.CommandArgument; // this is the ID of the clicked item
}
}
see: ASP.net GridView: get LinkItem's row
FindControl should work in this case.
protected void GrdViewUsers_RowDataBound(object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
HyperLink myHyperLink = e.Row.FindControl("Edit") as HyperLink;
}
}
First: You have repeating ID's in your TemplateFields like lblUsername what is not allowed since it's the same NamingContainer.
You can pass the RowIndex as CommandArgument to RowCommand:
on aspx:
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton
Text="Re-Take"
runat="server"
ID="Edit"
CommandName="Edit"
CommandArgument="<%# ((GridViewRow) Container).RowIndex %>">
</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
Handle the GridView's RowCommand:
void GrdViewUsers_RowCommand(Object sender, GridViewCommandEventArgs e)
{
if(e.CommandName=="Edit")
{
int index = Convert.ToInt32(e.CommandArgument);
GridViewRow row = GrdViewUsers.Rows[index];
// now you can get all of your controls like:
Label lblSurname = (Label)row.FindControl("lblSurname");
String email = lblSurname.Text // you noticed that DataItem.Email is bound to lblSurname?
}
}
Suppose the grid has linkbutton on which we want to get row index
<asp:LinkButton ID="lnkbtnAdd " runat="server" CommandName="cmdAdd" ImageUrl="~/Images/add.gif" ></asp:LinkButton>
In code behind, In OnRowCreated event we attach row number of grid to each button of row to get it back when it is clicked in RowCommand event
protected void gvListing_RowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
System.Web.UI.WebControls.LinkButton lnkbtnAdd = new System.Web.UI.WebControls.LinkButton();
lnkbtnAdd = (System.Web.UI.WebControls.LinkButton)e.Row.FindControl("lnkbtnAdd");
if (lnkbtnAdd != null)
lnkbtnAdd .CommandArgument = e.Row.RowIndex.ToString();
}
}
In RowCommand event we will get back the current row index and set the selected index of the grid
protected void gvListing_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName.ToString() == "cmdAdd")
{
int RowIndex = int.Parse(e.CommandArgument.ToString());// Current row
}
}

How to chage the properties for controls inside a template field?

I have a templatefield having a textbox and filteredtextboxextender inside the templatefield. I need to change the ValidChars property for filteredtextboxextender from "123" to "abc" in c# codebehind. The templatefield is there inside the GridView.
I used the following code in aspx page.
<asp:GridView ID="grdEducation" runat="server" AllowSorting="True" AutoGenerateColumns="False"
AllowPaging="false" CellPadding="4" GridLines="Vertical" OnRowDeleting="grdEducation_RowDeleting"
OnRowDataBound="grdEducation_RowDataBound" OnRowUpdating="grdEducation_RowUpdating" ShowFooter="false" ShowHeader="true">
<HeaderStyle CssClass="grid-header-style" />
<Columns>
<asp:TemplateField HeaderStyle-CssClass="grid-label-small" >`
<ItemTemplate>
<table>
<tr>
<td width='90%'>
<table>
<td width='60%'>
<asp:TextBox ID="textbox1" Width="100px" runat="server"
ToolTip="Provide text" MaxLength="11"></asp:TextBox>
<ajaxtoolkit:FilteredTextBoxExtender ID="filter" runat="server" TargetControlID="textbox1"
ValidChars="123" />
</td>
</table>
</td>
</tr>
</table>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Is there any possibility is there for change filteredtextboxextender property like that like that?
Thank you..
Register the RowBoundData event like below.
protected void GridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
YourControlType Conrol = (YourControlType)e.Row.FindControl("ControlID");
//Set the property here
}
}
You can similarly change the Control Properties in Row_Command event also

Access to datalist event inside another databound control & finding controls inside nested datalist

I have a DataList inside another DataList. I want to access the child DataList "dlQuestion" events, ItemDataBound event. Also, I'm tring to find the control LableControl "lblQuestion" in the child datalist. How do I do that? Here's the mark-up:
<asp:DataList ID="dlSection" runat="server" Width="100%">
<ItemTemplate>
<div>
<asp:Label ID="lblSection" runat="server" Text='<%# Eval("Section") %>'></asp:Label>
<asp:HiddenField ID="hfSectionId" runat="server" Value='<%# Eval("SectionId") %>' />
</div>
<asp:DataList ID="dlQuestion" runat="server" >
<ItemTemplate>
<asp:Label ID="lblQuestion" runat="server" Text='<%# Eval("Question") %>'></asp:Label></td>
<asp:HiddenField ID="hfQuestionId" runat="server" Value='<%# Eval("QuestionId") %>' />
</ItemTemplate>
</asp:DataList>
</ItemTemplate>
</asp:DataList>
You need to handle ItemDataBound event of the dlQuestion DataList and get lblQuestion Label in that event handler:
Markup:
<asp:DataList ID="dlSection" runat="server" Width="100%">
<ItemTemplate>
<div>
<asp:Label ID="lblSection" runat="server" Text='<%# Eval("Section") %>'></asp:Label>
<asp:HiddenField ID="hfSectionId" runat="server" Value='<%# Eval("SectionId") %>' />
</div>
<asp:DataList ID="dlQuestion" runat="server" OnItemDataBound="dlQuestion_ItemDataBound">
<ItemTemplate>
<asp:Label ID="lblQuestion" runat="server" Text='<%# Eval("Question") %>'></asp:Label></td>
<asp:HiddenField ID="hfQuestionId" runat="server" Value='<%# Eval("QuestionId") %>' />
</ItemTemplate>
</asp:DataList>
</ItemTemplate>
</asp:DataList>
Code-behind:
protected void dlQuestion_ItemDataBound(object sender, DataListItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
var lblQuestion = e.Item.FindControl("lblQuestion") as Label;
if (lblQuestion != null)
{
lblQuestion.ForeColor = Color.Red;
}
}
}
This is one way finding label control in child datalist...
//here I am finding item(DataList) of child Datalist
DataList dlSubChild = (DataList)childItem.FindControl("dlSubChild");
foreach (DataListItem subChildItem in dlSubChild.Items)
{
//here I am finding item(TextBox) of sub child Datalist
TextBox txtName = (TextBox)subChildItem.FindControl("txtName");
//set literal(litName) text
litName.Text = string.Format("{0}{1}", "Welcome ", txtName.Text);
}
i hope it will helps you ...

Categories

Resources