I have a label that is dynamically generated via a repeater, rollNo is a label that's a part of the itemTemplate. When I check the value of l, it goes in the if block but l.Text is still empty. check.Text only returns "d". Why?
Label l = (Label)item.FindControl("rollNo");
TextBox t = (TextBox)item.FindControl("quiz1");
if (l != null)
{
string a = l.Text;
check.Text = "d"+a;
}
Your code sample isn't complete as it has no rollNo in it, but I can tell you something...
You are using repeater and with that using template...The id you use inside the template is never will be the run-time id of any of your controls! Think about it! Let say you assigned rollNo to one of the elements in the template and you have 10 rows to pass to the repeater. Are you expecting to have 10 controls with the the same id of rollNo?! I hope not!
For that reason FindControl will return nothing while using on id inside a template...
You have to rethink what do you want or use a different approach to find the controls (loop)...
Repeater Markup:
<asp:Repeater id="Repeater1" runat="server" OnItemCommand="Repeater1_ItemCommand">
<ItemTemplate>
<tr onclick="rowReturn(this)">
<td><asp:Label CssClass="form-control" runat="server" ID="rollNo"><%# DataBinder.Eval(Container.DataItem, "sid") %></asp:Label></td>
<td><asp:TextBox CssClass="form-control" runat="server" ID="quiz1" required></asp:TextBox></td>
<td><asp:TextBox CssClass="form-control" runat="server" ID="quiz2" required></asp:TextBox></td>
<td><asp:Button CssClass="btn btn-success btn-sm form-control" ID="add" CommandName="add" runat="server" Text="Add" CommandArgument='<%#DataBinder.Eval(Container.DataItem, "sid") %>' /></td>
</tr>
</ItemTemplate>
Code Behind:
TextBox t1;
TextBox t2;
string rollNumber, T1, T2;
if (e.CommandName == "add")
{
// get CommandArgument you have selected on the button
string roll = e.CommandArgument.ToString();
rollNumber = roll;
foreach (RepeaterItem item in Repeater1.Items)
{
t1 = (TextBox)item.FindControl("quiz1");
t2 = (TextBox)item.FindControl("quiz2");
T1 = t1.Text;
T2 = t2.Text;
//...DB code or any other code
}
}
Related
Hey all — I'm trying to access the SelectedItem value from a DropDown list that is housed within a Repeater, but I am receiving a Null Exception that is thrown. This repeater would iterate over upwards of 10 "products". Here is the code from my Web Form:
<asp:repeater ID="rptProducts" runat="server" OnItemDataBound="rptProducts_ItemDataBound" OnItemCommand="rptProducts_ItemCommand">
<ItemTemplate>
<div class="col-md-8 col-md-offset-2 product">
<img src="<%# Eval("ImageFile") %>" class="col-xs-12" alt="<%# Eval("Name") %> Product Image"/>
<h3><%# Eval("Name") %></h3>
<p><%# Eval("ShortDescription") %></p>
<asp:DropDownList ID="DropDownList1" runat="server"></asp:DropDownList>
<asp:Button ID="Button1" runat="server" Text="Add to Cart" CommandName="click" CommandArgument='<%# Eval("Name") %>' UseSubmitBehavior="false" />
</div>
</ItemTemplate>
</asp:repeater>
And the code from the .cs file where I'm trying to access DropDownList1's SelectedItem value.
protected void rptProducts_ItemCommand(object sender, CommandEventArgs e)
{
Repeater rpt = (Repeater)sender;
DropDownList productDDL = (DropDownList)rpt.Items[0].FindControl("DropDownList1");
int Qty = Convert.ToInt32(productDDL.SelectedItem.Text);
Debug.WriteLine(rpt.ID);
if (e.CommandName == "click")
{
Debug.WriteLine("Clicked " + e.CommandArgument.ToString() + "; Quantity: " + Qty);
}
}
The Exception is being thrown at this line:
int Qty = Convert.ToInt32(productDDL.SelectedItem.Text);
I'm trying to prep that data to be pushed into a Session state, so I'm testing to ensure it is accessible. Is there something I'm missing and or a better way to access that specific value?
In rptProducts_ItemCommand event you are using fixed item index 0, you need to select the item that fired item command
Below line of code will select the current triggered item.
DropDownList productDDL = (DropDownList)((RepeaterCommandEventArgs)e).Item.FindControl("DropDownList1");
I have a button in a ListView that when its click it opens a modal with information relevant to the button that was clicked. I was able to get the index of the current listview item but I need to get the text from a label in both the previous item and next item. Heres what I have:
protected void List_ItemCommand(object sender, ListViewCommandEventArgs e)
{
ListViewDataItem dataItem = (ListViewDataItem)e.Item;
//Gets index of Listview
int DispalyIndex = e.Item.DisplayIndex;
int ItemIndex = e.Item.DataItemIndex;
Button index = (Button)dataItem.FindControl("TitleButton");
Label Name = (Label)dataItem.FindControl("LabelName");
}
I tried decrementing the index but no luck, anyone have an idea or a better solution? Thanks.
UPDATE
Heres my listviews, I use the first Listview to get the title and then the second to pull Jobs under the title. I bind both with a query using data bind
<asp:ListView ID="List" runat="server" OnItemCommand="List_ItemCommand" OnItemDataBound="List_ItemDataBound">
<LayoutTemplate>
<table>
<tr>
<asp:PlaceHolder ID="itemPlaceholder" runat="server"></asp:PlaceHolder>
</tr>
</table>
</LayoutTemplate>
<ItemTemplate>
<span class="label label-primary"><%# Eval("LabelName")%></span> <br />
<asp:ListView ID="JobList" runat="server" ItemPlaceholderID="JobPlaceHolder" OnItemDataBound="JobList_ItemDataBound">
<LayoutTemplate>
<asp:PlaceHolder runat="server" ID="JobPlaceHolder" />
</LayoutTemplate>
<ItemTemplate>
<br />
<asp:Button runat="server" ID="TitleButton" Text='<%# Eval("Job Title") %>' Font-Size="XX-Small" Font-Bold="true" CssClass="btn-xs btn-default" ClientIDMode="Static" OnClick="TitleButton_Click" />
</ItemTemplate>
<EmptyDataTemplate>
<br />
<b> <asp:Label runat="server" Text="There is no job for this Family and Level!" /></b>
</EmptyDataTemplate>
Try this
//null check before performing an operation, dataItem might be the first element in the page
//If so, prevItem will be null
var prevItem = List.Items[itemIndex - 1].FindControl("LabelName") as Label;
//null check before performing an operation, dataItem might be the last element in the page
//If so, nextItem will be null
var lastItem = List.Items[itemIndex + 1].FindControl("LabelName") as Label;
I have a Repeater that is binded with some DataTable. (Here I skiped header template).
<asp:Repeater ID="rpt_users" runat="server" OnItemCommand="rpt_users_ItemCommand" OnItemDataBound="rpt_users_ItemDataBound">
<ItemTemplate>
<tr class="c0">
<td><asp:CheckBox ID="CheckSelect" runat="server" /></td>
<td>
<asp:HyperLink ID="hpl_edit" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "name") %>'
NavigateUrl='<%# DataBinder.Eval(Container.DataItem, "edit") %>'></asp:HyperLink></strong>
<asp:LinkButton ID="btn_del" runat="server" CommandName="Remove" CommandArgument='<%# DataBinder.Eval(Container.DataItem, "key") %>'><img src="assets/img/delete.png" alt="<%#nodeDelete %>" title="<%#nodeDelete %>" class="ico-delpage icon-right" /></asp:LinkButton>
</td>
<td>
<p><%# DataBinder.Eval(Container.DataItem, "country") %></p>
</td>
<td>
<asp:TextBox runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "daysleft") %>' OnTextChanged="Unnamed_TextChanged" AutoPostBack="true"/>
</td>
</tr>
</ItemTemplate>
<asp:Repeater>
I associated OnTextChanged event with a handler:
protected void Unnamed_TextChanged(object sender, EventArgs e)
{
var txt = (sender as TextBox).Text;
int newDays = 0;
try
{
newDays = int.Parse(txt);
}
catch { return; }
}
So, how to get the whole object that is associated with current row in Repeater? I need to get access to this object in my OnTextChanged event handler, because I need to get some data from this object that represents current row.
You cannot access the bound object of the repeater item in the OnTextChanged event. One way of doing this is as follows.
After retrieving the datatable, save the datatable in viewstate
ViewState["Data"] = data;
Bind the key value of the individual item to a hidden field by adding a hidden field to the repeater item
< asp:HiddenField runat="server" ID="hiddenFieldKey" Value='<%# DataBinder.Eval (Container.DataItem, "key") %>' />
You can get the, repeater item and then the hidden field, to get the key of the row. Then the other values can be retrieved by finding the rows in the table which is stored in the viewstate.
protected void Unnamed_TextChanged(object sender, EventArgs e)
{
var txt = (sender as TextBox).Text;
var repeaterItem = (sender as TextBox).NamingContainer as RepeaterItem;
var hiddenFieldKey =repeaterItem.FindControl("hiddenFieldKey") as HiddenField;
// Get data from viewstate
DataTable data = ViewState["Data"] as DataTable;
var dataRow= data.Rows.Find(hiddenFieldKey.Value);
//You can use this row to get the values of the other columns
int newDays = 0;
try
{
newDays = int.Parse(txt);
}
catch { return; }
}
Another way of doing is that, if you dont have many values to get, then bind all the required values in multiple hidden fields in the repeater item and then get those hidden field values in the OnTextChanged event
You can use the sender parameter, like you do for Text, var tb = (TextBox)sender;, then access that control's Parent property. You might have to go a couple levels up to find exactly what you're looking for, but that's the gist. Then you can use FindControl or whatever you need past that.
I have a ASP.NET Application with a ListView. In every Row in my ListView I have a LinkButton that open a new webform "Benutzer.aspx". my Problem is that I don't get the Index of this Row. I use the ItemCommand Event but it not work :(
Here my Code:
ASPX:
...
<ItemTemplate>
<tr runat="server">
<td align="left" ><asp:Label ID="Label1" Text='<%# Eval("Benutzer") %>' runat="server" /></td>
<td align="left"><asp:Label ID="Label2" Text='<%# Eval("eMail") %>' runat="server" /></td>
<td align="left"><asp:Label ID="Label3" Text='<%# Eval("Vorname") %>' runat="server" /></td>
<td align="left"><asp:Label ID="Label4" Text='<%# Eval("Nachname") %>' runat="server" /></td>
<td align="left"><asp:Label ID="Label5" Text='<%# Eval("Telefon") %>' runat="server" /></td>
<td align="left"><asp:LinkButton runat="server" Text="Anzeigen" CommandName="Anzeigen" OnCommand="ListView1_ItemCommand" CommandArgument="myArguments"></asp:LinkButton></td>
</tr>
</ItemTemplate>
...
cs file:
...
protected void ListView1_ItemCommand(object sender, ListViewCommandEventArgs e)
{
if (e.CommandName == "Anzeigen")
{
Label lbText = (Label)e.Item.FindControl("Label2");
string email = lbText.Text;
Session["email"] = email;
Response.Redirect("Benutzer.aspx");
}
}
...
What is the matter :(
tarasov
Try this:
First you need to have the index of the button. So in the html code add this in the CommandArgument of the button to get the index:
CommandArgument='<%# Container.DataItemIndex %>'
Then in the codebehind:
if (e.CommandName == "Anzeigen")
{
Label lbText = ListView1.Item[e.CommandArgument].FindControl("Label2");
string email = lbText.Text;
Session["email"] = email;
Response.Redirect("Benutzer.aspx");
}
Hope I Helped
You cannot find the control because it is contained in the child control collection of another server control:
<tr runat="server">
You need to try to find the control recursively:
Take a look
Better way to find control in ASP.NET
Or you can use this extension method:
public static class ControlExtensions
{
public static Control FindControlRecursively(this Control control, string targetControlID)
{
if (control == null)
{
return null;
}
var ctrl = control.FindControl(targetControlID);
if (ctrl == null)
{
foreach (Control child in control.Controls)
{
ctrl = FindControlRecursively(child, targetControlID);
if (ctrl != null)
{
break;
}
}
}
return ctrl;
}
}
Usage:
var ctrl = e.Item.FindControlRecursively("your control ID");
The code you have furnished is simply fine... "just remove the 'CommandArgument' from your listview property , bcoz..its already have the dataindex you are looking for. By specifying a command argument you are overriding the default one.
So just remove the command argument and your code will work fine... :)
I am a VB programmer Check this method may b it gives you some idea
after binding the list with datasource, In the itemCommand do this
Dim <sometext> As Label = TryCast(e.Item.FindControl("Anzeigen"), Label)
If e.CommandName = "Anzeigen" Then
'do what ever you like
'also you can use <sometext> if you want to extract data from list
'simply use <sometext>.<whatproperty>, you can also store it in sessions like the email you are using.
Session("email") = email
Response.Redirect("Benutzer.aspx");
End If
let me know if it helps you solve your problem.
This is the HTML, then build the OnItemCommand.
<asp:ListView ID="lvFiles" runat="server" DataKeyNames="FileName" OnItemCommand="lvFiles_ItemCommand">
<ItemTemplate>
<tr runat="server">
<td style="width:80px">
<asp:LinkButton runat="server"
ID="SelectEmployeeButton"
Text="Download File"
CommandName='<%#Eval("FileName")%>'
CommandArgument='<%#Eval("FileName")%>' />
</td>
</tr>
</ItemTemplate>
</asp:ListView>
Here is the code behind...
protected void lvFiles_ItemCommand(object sender, ListViewCommandEventArgs e)
{
string v = e.CommandArgument.ToString();
}
<asp:Repeater ID="rptList" runat="server">
<HeaderTemplate>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td width="15%">
<b>Subject</b>
</td>
<td width="60%">
<%#Eval("Title")%>
</td>
</tr>
I do databind to a repeater, and bind the title value.
string MysqlStatement = "SELECT Title, RespondBy FROM tbl_message WHERE MsgID = #Value1";
using (DataServer server = new DataServer())
{
.. }
rptList.DataSource = ds;
rptList.DataBind();
How can I get the value of title in server side, when a button in clicked in the same page.
I would put the title in a server control, like a label, and then you can do something like this:
<asp:Repeater ID="rptList" runat="server">
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%#Eval("Title")%>' />
</ItemTemplate>
</asp:Repeater>
And then in the code behind:
int itemIndex = 0;
Label lbl = rptList.Items[itemIndex].FindControl("Label1") as Label;
if (lbl != null)
{
string labelValue = lbl.Text;
}
I would set the value of title to the text of a label that you could call FindControl() on.