Accessing a button in a repeater from Code Behind (C#) - asp.net

I am finding some serious problems in accessing a button placed in a repeater from code behind.
This is the repeater code:
<asp:Repeater ID="Repeater1" runat="server">
<HeaderTemplate></HeaderTemplate>
<ItemTemplate>
<table>
<tr>
<td>Username:</td>
<td> <%# Eval("UserName") %></td>
</tr>
<tr>
<td>Date:</td>
<td><%# Eval("CommentTime") %></td>
</tr>
<tr>
<td>Comment:</td>
<td><%# Eval("Comment") %></td>
</tr>
<tr>
<td>
<asp:Button ID="btnDeleteComment" runat="server" Text="Delete" /></td>
</tr>
</table>
<br />
</ItemTemplate>
</asp:Repeater>
And This is the code Behind placed int the page load:
Button btn = new Button();
btn = (Button)Repeater1.FindControl("btnDeleteComment");
btn.Visible = false;
Am I missing something?
Thanks

I am sure, I've solved your problem as to why you are getting the object reference not set.
As you have this conditional statement, if (e.Item.ItemType == ListItemType.Item), when its first iterates it will be a header item type. Since your your button is in the item template, that's doesn't exist in the Header template.
protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item)
{
Button btn = new Button();
btn = (Button)e.Item.FindControl("btnDeleteComment");
btn.Visible = false;
}
}

You can't find the control like this. What you need to do is attach an event to repeater "item data bound event" and in that event handler do:
(Button)e.Item.FindControl("btnDeleteComment");

on .aspx
<asp:Button ID="btnDeleteComment" runat="server" Text="Delete" Visible='<# IsAuthor?"true":"false" >' />
in code behind
//global scope
public bool IsAuthor=false;
//in pageload event
IsAuthor= GetIsAuthor();

Related

Next textbox disable in ASP.net

I want to add one validation like if Status is "Accept" then QtyRejected get disable
Below is my ASP code for status and qtyRejected
<td>
<asp:DropDownList ID="lAccept" runat="server" Height="25px" Width="102px">
<asp:ListItem>Accept</asp:ListItem>
<asp:ListItem>Reject</asp:ListItem>
</asp:DropDownList>
</tr>
<tr>
<td width="30%">
<b>Qty Rejected:</b>
</td>
<td>
<asp:TextBox ID="lRejectedQty" runat="server" CausesValidation="True"></asp:TextBox>
<%-- <asp:CustomValidator ID="CustomValidator1" runat="server"
ErrorMessage="Only interger between 1 to 10000000 " ondisposed="Page_Load"
oninit="Page_Load" onservervalidate="CustomValidator1_ServerValidate"></asp:CustomValidator>--%>
</td>
</tr>
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack)
{
if (lAccept.SelectedItem.Text == "Accept")
{
lRejectedQty.Enabled = false;
}
}
}
You should be able to retrieve the selected value of the dropdownlist using jQuery with something like this.
$('#<%= lAccept.ClientID %> option:selected').val();
Then you can disable your textbox with a little more jQuery with something like this.
$('#<%=lRejectedQty.ClientID %>').attr("disabled", "disabled");
And if you want to re-enable.
$('#<%=lRejectedQty.ClientID %>').removeAttr("disabled");
Hope this helps.

asp.net string to listviewitem

I have a control (ascx) that has an itemtemplate for inserted service locations. What I am trying to do is OnDataBound event have an item already added upon the listview showing. The listview is for city and state. I have been trying to use the ListViewItemInsertArgs, but the signature is wrong. Been trying to figure this out for days..
protected void lvServiceLocations_DataBound(object sender, EventArgs e)
{
ListView lv = sender as ListView;
var lvi = new ListViewDataItem(0, 0);
lvi.DataItem = da_User_Data.Select_Applicant_Specific_Results(userProfileId, dlControlId); //this returns a string
lv.Items.Insert(0, lvi);
}
<asp:ListView ID="lvServiceLocations" runat="server" DataSourceID="sdsServiceLocations" DataKeyNames="user_service_location_id" InsertItemPosition="FirstItem"
OnItemInserting="lvServiceLocations_ItemInserting"
OnDataBound="lvServiceLocations_DataBound">
<LayoutTemplate>
<table class="location-selection-table ui-widget-content">
<tr><th colspan="4" class="ui-widget-header">Locations</th></tr>
<tr id="itemPlaceHolder" runat="server" />
</table>
</LayoutTemplate>
<ItemTemplate>
<tr class="location-selection-item-row">
<td class="location-selection-actions"><asp:LinkButton runat="server" Text="Remove" CommandName="Delete" /></td>
<td><%# Eval("selected_state") %></td>
<td><%# Eval("selected_county") %></td>
<td class="location-selection-actions"></td>
</tr>
</ItemTemplate>
DataBound event will only occur if you call the DataBind method, and it will only occur once either Page.DataBind or Ctrl.DataBind is called but in any case it is not in this method where you have to insert the new item but instead you have to add it to the Source of the data set in the datasource and then you reset the control with a DataBind method call.
So you have to insert the new item into the source associated with sdsServiceLocations and not directly into the control

wont display drop down

<form>
<asp:Repeater id="rptComments" runat="server">
<HeaderTemplate>
<table class="detailstable FadeOutOnEdit">
<tr>
<th style="width:200px;">Answers</th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<th style="width:200px;"><asp:DropDownList ID="dropDownForChecklistAnswers" runat="server" /></th>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
<asp:Button id="button" text="Submit" OnClick="Page_Load" runat="server" />
</FooterTemplate>
</asp:Repeater>
</form>
Code Behind:
List<Checklist_Record_Choice> CLRC =
(from choice in db.Checklist_Record_Choices
select choice).ToList();
dropDownForChecklistAnswers.DataSource = CLRC;
DropDownList1.DataTextField = Text;//Text being the name of column2 in the table (which contains yes, no, n/a)
dropDownForChecklistAnswers.DataBind();
ERROR: dropDownForChecklistAnswers does not exist in the current context???
please advise
EDIT;
thanks for reply. I have
public void OnReptDataBound(object sender, RepeaterItemEventArgs e)
{
ClarkeDBDataContext db1 = new ClarkeDBDataContext();
List<string> CLRC =
(from choice in db1.Checklist_Record_Choices
select choice.Text).ToList();
DropDownList ddl = (DropDownList)e.Item.FindControl("dropDownForChecklistAnswers");
ddl.DataSource = CLRC;
}
but DropDownList ddl is coming back as object ref not set to instance of an object...why is it null??
You need to use FindControl to access a control which is part of a Repeater's template.
Subscribe to the OnItemDataBound of the Repeater (set the attribute OnItemDataBound="OnReptDataBound")
And then in your code behind do the following
void OnReptDataBound(object sender, RepeaterItemEventArgs e)
{
if(e.Item.ItemType == ListItemType.Item)
{
DropDownList ddl = (DropDownList )e.Item.FindControl("dropDownForChecklistAnswers");
ddl.DataSource = ....

ListView find dropdownlist in table

I have a list view with table inside and i need to get all dropdown lists and file upload controls, but find returns nothing. This is my code:
<asp:ListView runat="server" ID="MyListView" OnItemDataBound="FillDropDownList">
<LayoutTemplate>
<table border="0" cellpadding="2" cellspacing="0">
<tr>
<th>Wholesaler</th>
<th>Import</th>
<th>Period</th>
<th>Upload Date</th>
<th>Upload</th>
</tr>
<asp:PlaceHolder ID="itemPlaceholder" runat="server" />
</table>
</LayoutTemplate>
<ItemTemplate>
<tr class="row1">
<td><%# DataBinder.Eval(Container.DataItem, "Wholesaler") %></td>
<td><%# DataBinder.Eval(Container.DataItem, "Import")%></td>
<td><%# DataBinder.Eval(Container.DataItem, "Period")%></td>
<td><asp:DropDownList runat="server" ID="DaysDropDownList"></asp:DropDownList></td>
<td><asp:FileUpload ID="FileUpload" runat="server" /></td>
</tr>
</ItemTemplate>
</asp:ListView>
DropDownList dr = (DropDownList)MyListView.Controls[0].FindControl("DaysDropDownList");
FileUpload fl = (FileUpload)MyListView.Controls[0].FindControl("FileUpload");
figured...and you got that error, because the listview was not binded yet, so i think the best way would be to do all this on the ItemDataBound event. You would find the dropdownlist like:
protected void FillDropdownlist(object sender, ListViewItemEventArgs e)
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
DropDownList dr = (DropDownList)e.Item.FindControl("DaysDropDownList");
FileUpload fl = (FileUpload)e.Item.FindControl("FileUpload");
if (dr!= null)
{
//code here
}
}
}
You need to iterate over the Items collection of the listview, and then use FindControl on each item. Something like this should put you on the right track:
foreach (var lvItem in MyListView.Items)
{
if (lvItem.ItemType == ListViewItemType.DataItem)
{
DropDownList dr = (DropDownList)lvItem.FindControl("DaysDropDownList");
FileUpload fl = (FileUpload)lvItem.FindControl("FileUpload");
}
}
That's because MyListView.Controls[0] points to an inner control that does not contain those two.
Try debugging and finding precisely which is your container control, and then accessing it directly without a hard coded index. It's accessible via the event parameter of your row binding calls.
Also might I suggest you use the as operator as it doesn't raise an exception:
The as operator is like a cast except that it yields null on conversion failure instead of raising an exception
i.e.
DropDownList dr = e.Item.FindControl("DaysDropDownList") as DropDownList;
FileUpload fl = e.Item.FindControl("FileUpload") as FileUpload;
or after it's bound
//Loop i for the items of your listview
DropDownList dr = MyListView.Items[i].FindControl("DaysDropDownList") as DropDownList;
FileUpload fl = MyListView.Items[i].FindControl("FileUpload") as FileUpload;

ListView fields not getting posted

I know I've done something like this before, but I have no idea why it isn't working now. I have a ListView with some textboxes. I want to read the text out of those boxes when I click a button (linkbutton, whatever).
<asp:ListView runat="server" ID="lv_bar" EnableViewState="true">
<LayoutTemplate>
<table>
<tr>
<th>Foo</th>
</tr>
<tr runat="server" id="itemPlaceholder"></tr>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td><asp:LinkButton ID="lb_delete" CausesValidation="false" runat="server" Text="Del" /></td>
<td><asp:TextBox id="txt_foo" runat="server" /></td>
</tr>
</ItemTemplate>
</asp:ListView>
<asp:LinkButton ID="lb_add" CausesValidation="false" runat="server" Text="Add" />
And then here's the relevant code-behind stuff:
protected void Page_Load(object sender, EventArgs e)
{
lb_chapter_add.Click += lb_chapter_add_Click;
if (!IsPostBack)
{
lv_chapters.DataSource = new List<Foo>() { new Foo() { Name = "harbl"} };
lv_chapters.DataBind();
}
}
void lb_add_Click(object sender, EventArgs e)
{
foreach (ListViewDataItem item in lv_bar.Items)
{
var txt_foo = (TextBox)item.FindControl("txt_foo");
Response.Write("foo: " + txt_foo.Text);
}
Response.Write("<br />the end");
Response.End();
}
But what I see when I enter some text into txt_foo and click lb_add is just "the end". What am I doing wrong here?
The problem it that you are using a a non persistent object as DataSource.
Due to clicking the button, you generate a postback and lv_chapters does not contain any items. Set a breakpoint in the line where the foreach is and you will see that lv_chapters.Items in null, or that it's Count property returns 0.

Resources