ListView find dropdownlist in table - asp.net

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;

Related

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 = ....

how to add sorting function in repeater in asp 2.0?

I m using asp 2.0, I need an requirement for sorting the repeater control. I search over the Internet but i could nt find the correct solution. If anyone knows the answer please help to solve my problem.
You need to sort the collection before binding to the repeater.
If you want to dynamically sort on post backs, sort in the event handler before re-binding to the repeater.
This article explains how to add sort functionality to a Repeater or a DataList control. It might help to your purpose or at least as a guide.
Finally i got the Sorting output in Repeater Control.
1.Maintaining the Static Variable;
static int count = 0;
2.In LinkButton click Event
protected void lnkreq_name_click(object sender, EventArgs e)
{
count=Convert.ToInt32(ViewState["count"].ToString());
ViewState["count"] = count;
loadRepeater("REQUEST_NAME",count);
}
3.call the Function
protected void loadRepeater(string reqname,int count)
{
//write the code to bind into Dataset
DataView dv = ds.Tables[0].DefaultView;
if (count == 0)
{
dv.Sort = reqname + " asc";
ViewState["count"] = 1;
}
else if (count == 1)
{
dv.Sort = reqname + " desc";
ViewState["count"] = 0;
}
//then bind into repeater
}
4.In Repeater
<asp:Repeater runat="server" ID="RepeaterEntry" >
<HeaderTemplate >
<table class="list_table" border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<th><asp:LinkButton ID="lnkreq_name" runat="server" ForeColor="white" OnClick="lnkreq_name_click" >Request Name</asp:LinkButton></th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td><%# Eval("REQUEST_NAME")%></td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>

Render empty repeater

When Repeater contains no items it's not get rendered in HTML at all, even HeaderTemplate or FooterTemplate. I need to manipulate it on client-side even if it's empty.
Is there any way to always render Repeater in HTML?
In the <FooterTemplate>, add a Label with some empty data text and set its visible property to false.
<FooterTemplate>
<table>
<tr>
<td>
<asp:Label ID="lblEmptyData"
Text="No Data To Display" runat="server" Visible="false">
</asp:Label>
</td>
</tr>
</table>
</FooterTemplate>
Now check the the data while binding repeater, if no rows return then make label visible otherwise no action.
More details here.
as #Saurabh said, use <FooterTemplate> add a Label with specifying your message in the Text property and set its visible property to false like this:
<FooterTemplate>
<%-- Label used for showing Error Message --%>
<asp:Label ID="ErrorMessage" runat="server" Text="Sorry!!" Visible="false">
</asp:Label>
</FooterTemplate>
Then in the code-behind use the following logic; if there is no data, show the message, otherwise, show the data as following:
protected void Repeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
Repeater rpt = sender as Repeater; // Get the Repeater control object.
// If the Repeater contains no data.
if (rpt != null && rpt.Items.Count < 1)
{
if (e.Item.ItemType == ListItemType.Footer)
{
// Show the Error Label (if no data is present).
Label ErrorMessage = e.Item.FindControl("ErrorMessage") as Label;
if (ErrorMessage != null)
{
ErrorMessage.Visible = true;
}
}
}
}
<asp:Repeater ID="rptList" runat="server" DataSourceID="odsList">
...
<FooterTemplate>
<%if (rptList.Items.Count == 0)
{ %>
**Your message**
<%} %>
</FooterTemplate>
</asp:Repeater>
Try this
protected bool IsDataEmpty
{
get
{
ICollection list = Repeater1.DataSource as ICollection;
return list.Count == 0 ? true : false;
}
}
In Markup :
<table width="80%">
<tr runat="server"
visible='<%# IsDataEmpty %>'>
<td>
There is no data to display
</td>
</tr>
for step by step follow the link :Link

Accessing a button in a repeater from Code Behind (C#)

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();

Resources