<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 = ....
Related
i have a Listview that i use like a gridview. inside the itemtemplate i have only a 'modifyble' field, a dropdownlist.
I would like to fire a 'Save' event when user change the dropdownlist. I know i have to set up the autopostback = true of the dropdownlist but i don't know how to fire the event because visual studio don't allow me to create the 'on change event' of the dropdownlist when it is inside a listview.
This is my code example
<asp:ListView ID="lvDmr" runat="server" DataSourceID="dsDmr" DataKeyNames="id">
<ItemTemplate>
<table style="width: 100%;" cellspacing="0" cellpadding="8">
<tr style="width: 100%;">
<td class="colonna-griglia" style="width: 5%;">
<%# Convert.ToDateTime(Eval("data_rilevazione")).ToString("d") %>
</td>
<td class="colonna-griglia">
<%# Eval("rivista")%>
</td>
<td class="colonna-griglia">
<asp:DropDownList runat="server" ID="myComboBox" DataSourceID="dsAgenti" DataTextField="customer"
DataValueField="customer" Width="150px" AutoPostBack="true">
</asp:DropDownList>
</td>
...
....
</asp:listview>
You may not get this in designer view, but if you directly add event handler it will definitely work. Following are code snippet for this.
Add OnSelectedIndexChanged="myComboBox_SelectedIndexChanged" to myComboBox.
<asp:DropDownList runat="server" ID="myComboBox" DataSourceID="dsAgenti" DataTextField="customer"
DataValueField="customer" Width="150px" AutoPostBack="true" OnSelectedIndexChanged="myComboBox_SelectedIndexChanged">
</asp:DropDownList>
Next in serverside , use following for event handler.
protected void myComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
DropDownList ddlListFind = (DropDownList)sender;
ListViewItem item1 = (ListViewItem)ddlListFind.NamingContainer; // item1, is current row of Listview, which hold the dropdownlist that caused postback.
}
More help - http://forums.asp.net/t/1357900.aspx?SelectedIndexChanged+of+a+DropDownList+which+is+inside+a+ListView
protected void dropdownlist1_SelectedIndexChanged(object sender, EventArgs e)
{
DropDownList ddl = (DropDownList)sender;
ListViewItem dst = (ListViewItem)ddlListFind.NamingContainer;
DropDownList gddl = (DropDownList)dst.FindControl("dropdownlist1");
HiddenField hid_msg = (HiddenField)item1.FindControl("hidmsg");
hid_msg.Visible = true; hid_msg.Value = "Dropowntext : " + gddl.SelectedItem.Text.Trim() + " and value of dropdown is : " + gddl.SelectedItem.Value.Trim();
}
Or visit this link for more detail:
https://forums.asp.net/t/1357900.aspx?SelectedIndexChanged+of+a+DropDownList+which+is+inside+a+ListView
I have an asyncfileupload control and a repeater that I would like to use to show list of added files. On FileUploadedComplete event I add the new file's name and size to a data table and use it to bind the repeater. I can select a file and add it (SaveAs()), add the info to data table (I can see it is there) but after calling repeater's databind() nothing happens, can't see the file data.
This is what I have (watered down version):
<asp:UpdatePanel runat="server" ID="upnlFU">
<ContentTemplate>
<ajaxToolkit:AsyncFileUpload
runat="server"
ID="fuAttchedDocs"
ThrobberID="myThrobber"
UploaderStyle="Modern"
onuploadedcomplete="fuAttchedDocs_UploadedComplete"
onuploadedfileerror="fuAttchedDocs_UploadedFileError" />
<asp:Repeater runat="server" ID="rptAttachments">
<HeaderTemplate>
<table>
<tr>
<td>File Name</td>
<td>File Size</td>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td><%# Eval("FileName")%></td>
<td><%# Eval("FileSize")%></td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
</ContentTemplate>
</asp:UpdatePanel>
Code behind:
DataTable dtAttachments;
protected void Page_Load(object sender, EventArgs e)
if (!Page.IsPostBack)
{
dtAttachments = new DataTable();
dtAttachments.Columns.Add("FileName", Type.GetType("System.String"));
dtAttachments.Columns.Add("FileSize", Type.GetType("System.Int32"));
dtAttachments.AcceptChanges();
}
else
{
dtAttachments = (DataTable)ViewState["Attachments"];
}
BindAndSaveAttachmentData();
}
void BindAndSaveAttachmentData()
{
ViewState["Attachments"] = dtAttachments;
rptAttachments.DataSource = dtAttachments;
rptAttachments.DataBind();
}
protected void fuAttchedDocs_UploadedComplete(object sender, AsyncFileUploadEventArgs e)
{
string sFileName = fuAttchedDocs.FileName;
string sFileSize = e.FileSize;
fuAttchedDocs.SaveAs(FilePath.TEMP_FOLDER + sFileName); // Saving to d:\blah\yada temporary folder
dtAttachments.Rows.Add(new object[] { sFileName, int.Parse(sFileSize) });
BindAndSaveAttachmentData();
}
Both file upload and repeater are inside an update panel.
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;
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();
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.