ASP.NET Accessing web control inside DataList control - asp.net

Am not sure why I cannot access my Label control which was inside the Panel and the Panel is inside the DataList
<asp:DataList ID="DataList2" runat="server" DataSourceID="SqlDataSource1" Width="100%">
<ItemTemplate>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<!-- post details -->
<td style="width: 60%">
<asp:Panel ID="panelPostDetails" runat="server" CssClass="postpage_details">
<table border="0" cellpadding="5" cellspacing="0" width="100%">
<tr>
<td colspan="2"><div class="postpage_header"><%# Eval("Heading") %></div></td>
</tr>
<tr>
<td>
<img src="picserver/posts/<%# Eval("ImagePath") %>/1.jpg" alt="preview" style="width: 240px;" />
<div id="morepictures">
<asp:Label ID="lblMorePictures" runat="server" />
</div>
</td>
<td>
<div style="padding: 0px 5px 0px 5px;">
<div>
more stuff here
</div>
</div>
</td>
</tr>
</table>
</asp:Panel>
<asp:RoundedCornersExtender ID="RoundedCornersExtender1" runat="server"
Radius="6"
Corners="All"
TargetControlID="panelPostDetails"></asp:RoundedCornersExtender>
</td>
</tr>
</table>
</ItemTemplate>
</asp:DataList>
but when I tried using "lbl" in Page_Load, it seems it cannot find the control? can you please help me?
ItemDataBound and Page_Load event
---------------------------------
Panel p = DataList2.FindControl("panelPostDetails") as Panel;
Label l = p.FindControl("lblMorePictures") as Label;
l.Text = code;
that code returns Object reference not set to an instance of an object.
Thanks in advance
update:
ItemDataBound and Page_Load event
---------------------------------
Panel p = DataList2.FindControl("panelPostDetails") as Panel;
if(p==null)
{
System.Diagnostic.Debug.WriteLine("panel does not exist");
}
else
{
System.Diagnostic.Debug.WriteLine("panel does exist");
}
output:
panel does not exist
what on earth is going on!?!

Typically, you access controls like this at runtime by handling either the DataList's ItemCreated or ItemDataBound event. Here's a sample event handler:
protected void DataList2_ItemDataBound(object sender, DataListItemEventArgs e) {
if (e.Item.ItemType == ListItemType.Item) {
Label lbl = (Label)e.Item.FindControl("panelPostDetails").FindControl("lblMorePictures");
lbl.Text = code;
}
}
Wire up your the event handler like this:
<asp:DataList ID="DataList2" runat="server" OnItemDataBound="DataList2_ItemDataBound" ...

#Peter's code must work.
you can also try this:
protected void DataList2_ItemDataBound(object sender, DataListItemEventArgs e)
{
string st= (e.Item.FindControl("lblMorePictures") as Label).Text;
}
and put breakpoint to wath to st. In my case I get a text of lblMorePictures.

With my Form View I needed to add CType to the FindControl. I understand DataList doesn't necessarily need the Ctype however it is possible the Panel may need this prefix. In this case frmDelView is the name of my Form View. In my case the code line below is in my PreRender of my form. That was the only place at the time of creating the form it would return the data I needed to pass to a label on a next page of a Wizard Step page. Long story.
Note: my code is vb and not C#. It should be nearly or exactly the same.
CType(frmDelView.FindControl("txtcboDAcct"), TextBox).Text

Related

How can i fetch data of checked checkbox in repeater when click on button?

I have code of repeater like this .Now when i click on button i want job_id of selected checkbox.
`<asp:Repeater ID="rptJob" runat="server" >
<ItemTemplate>
<td valign="middle" style="padding-left: 10px; padding-right: 10px">
<table align="center" cellpadding="0" cellspacing="0" border="0" width="604">
<tr>
<td width="3%" valign="top">
<asp:CheckBox ID="CheckBox1" runat="server" CssClass="search-link"/>
</td>
<td valign="middle" align="left">
<a href="display_job.aspx?jobId=`<%# Eval("job_id")`%>&empId= "` # Eval("emp_id") %>"` target="_blank">
<asp:Label ID="title" runat="server">
<%#DataBinder.Eval(Container.DataItem, "job_title")%> </asp:Label>
</a> </td>
</asp:Repeater>`
In code behind what i have to write on button click event?
There are a number of ways to solve this issue. Assuming the button click causes a postback I'd choose one of the two:
Switch to the ListView control (instead of the Repeater) and utilize this DataKeyNames property. You'll need to add a handler for the CheckBox's CheckChanged event as well. The accepted answer here should be of help in implementing the handler: http://forums.asp.net/t/1581511.aspx/1
Subclass the CheckBox control and add a property to store the job ID. Add a handler for the CheckChanged event (in the handler, cast the sender argument to your newly subclassed checkbox). In the aspx/ascx page, bind the job_id to the newly added property.
[ToolboxData(#"<{0}:JobCheckBox runat=""server""></{0}:JobCheckBox>")]
public class JobCheckBox : CheckBox
{
[Category("Data")]
[DefaultValue(0)]
[Description("The Job ID associated with this checkbox.")]
// Assuming the job ID is an int
public int JobId
{
get { return (ViewState["JobId"] is int) ? (int)ViewState["JobId"] : 0; }
set { ViewState["JobId"] = value; }
}
}

GridView Custom PagerTemplate, Show Hide Previous and Next Links

I have the following PagerTemplate. I need to hide the Previous link when user is viewing the first page and hide the Next link if user is viewing the Last page.
<PagerTemplate>
<table border="0" style="width: 100%;">
<tbody>
<tr>
<td style="float: right;">
<asp:LinkButton CommandName="Page" CommandArgument="Prev" ID="LinkButton2" runat="server"><< Previous</asp:LinkButton>
<asp:LinkButton CommandName="Page" CommandArgument="Next" ID="LinkButton3" runat="server" >Next >></asp:LinkButton>
</td>
<td style="clear: both"></td>
</tr>
</tbody>
</table>
</PagerTemplate>
Grid's PageIndex and PageCount properties will help you here - Prev link should be shown/enabled only when PageIndex > 0 while Next link should be shown/enabled only when PageIndex < PageCount - 1.
Use row created event to find controls and alter the visibility. For example,
protected void GridView_RowCreated(Object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.Pager)
{
var prev = (LinkButton)e.Row.FindControl("LinkButton2");
prev.Visible = Grid.PageIndex > 0;
var next = (LinkButton)e.Row.FindControl("LinkButton3");
next.Visible = Grid.PageIndex < grid.PageCount - 1;
}
}
I am not sure of you need a custom template for current UI. You can use pager settings - for example,
<pagersettings mode="NextPrevious"
nextpagetext="Next >>"
previouspagetext="<< Previos"
position="Bottom"/>
And use PagerStyle for styling the UI.
<PagerStyle CssClass="myPager" />

ASP:Labels not updating on button Click

I know this is probably something so simple that I am just not able to see it. I have an aspx form that has a usercontrol in an updata panel. The user control is a people picker the searches on users from a corporate database.
What I want to see happen is:
The user clicks on a pick user button
The update panel with people picker becomes visible
They search for a user and then select the one they want.
When they make the selection and click Done, I get the user id of the user and look them up in our user table.
The user information should show up in a the form in label fields.
I can step through the code and see that I am getting the user information and that the label text is being set to the values but the page never updates the labels. It is a postback so I would think they would update.
<tr>
<td colspan="4">
<asp:UpdatePanel ID="CollapseDelegate" runat="server">
<ContentTemplate>
<asp:Panel ID="pDelegateHeader" runat="server">
<div style="padding: 10px 0 10px 20px; height:10px; text-align: left; background-color:#ffffff; color:#000000; border: 2px solid #ccc;" >
<asp:Label ID="ShowDelegate" runat="server" /><br />
</div>
</asp:Panel>
<asp:Panel ID="pDelegateBody" runat="server">
<PP:PeoplePicker ID="PP" runat="server" />
<asp:Button ID="btnOk" runat="server" Text="Done" CssClass="Buttons" onclick="btnOk_Click" />
</asp:Panel>
<asp:CollapsiblePanelExtender ID="CollapsiblePanelExtender3" runat="server" TargetControlID="pDelegateBody" CollapseControlID="pDelegateHeader" ExpandControlID="pDelegateHeader" Collapsed="true" TextLabelID="ShowDelegate" CollapsedText="Pick User..." ExpandedText="Close..." CollapsedSize="0"></asp:CollapsiblePanelExtender>
</ContentTemplate>
</asp:UpdatePanel>
</td>
</tr>
<tr>
<td><asp:Label ID="DelegateNameLabel" runat="server" Text="Name:" CssClass="indentedText" /></td>
<td><asp:Label ID="DelegateNameValueLabel" runat="server" CssClass="indentedText" Visible="true"></asp:Label></td>
<td><asp:Label ID="DelegateEmailLabel" runat="server" Text="Email:" CssClass="indentedText" /></td>
<td><asp:Label ID="DelegateEmailValueLabel" runat="server" CssClass="indentedText" Visible="true"></asp:Label></td>
</tr>
<tr>
<td><asp:Label ID="DelegatePhoneLabel" runat="server" Text="Phone:" CssClass="indentedText" /></td>
<td><asp:Label ID="DelegatePhoneValueLabel" runat="server" CssClass="indentedText" Visible="true"></asp:Label></td>
<td><asp:Label ID="DelegateVerifiedLabel" runat="server" Text="Last Verified Date:" CssClass="indentedText" /></td>
<td><asp:Label ID="DelegateVerifiedValueLabel" runat="server" CssClass="indentedText" /></td>
</tr>
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
string PassedDelegateID = string.Empty;
string Mode = string.Empty;
int delegateId = 0;
if (Request.QueryString["Id"] != null)
{
PassedDelegateID = Request.QueryString["Id"].ToString();
}
else
{
PassedDelegateID = "0";
}
if (Request.QueryString["mode"] != null)
{
Mode = Request.QueryString["mode"].ToString();
}
else
{
Mode = "add";
}
if (Mode == "add")
{
pnlUdpateDelegateText.Text = UIConstants.ADDDELEGATETEXT.ToString();
}
else
{
pnlUdpateDelegateText.Text = UIConstants.UPDATEDELEGATETEXT.ToString();
if (int.TryParse(PassedDelegateID, out delegateId))
{
loadDelegateData(delegateId);
}
}
}
}
protected void btnOk_Click(object sender, EventArgs e)
{
TextBox txtSearchValue = (TextBox)PP.FindControl("txtSearchResults");
string LanId = txtSearchValue.Text;
User user = BusinessUtility.GetUser(LanId);
DelegateNameValueLabel.Text = user.Name;
DelegateEmailValueLabel.Text = user.Email;
DelegatePhoneValueLabel.Text = user.Phone;
DelegateVerifiedValueLabel.Text = DateTime.Now.ToShortDateString();
}
Thanks,
Rhonda
Because the labels are outside the update panel, only the content inside the update panel is updated from an ajax post-back, that's the whole point of an update panel.
You will need to either move the labels inside the update panel's content area, or have another update panel for the labels and make it's update mode "always"
Your lables are outside of the UpdatePanel.
Under the hood, ASP.Net performes a full postback, but only the part that pertains to your UpdatePanel is transfered back down to the client. Some JavaScript then takes this bit of HTML and replaces the existing <div> element that is your UpdatePanel.
Since your labels are outside of that <div> they never get updates.

Add new row in table in code behind problem

I have table on my asp.net page, and I want to insert new rows.I try to add on every click on button new row which contain cell with FileUpload, but it works only for first time. When I click next time, in my code behind table.
<asp:Panel ID="pnlImages" runat="server" BackColor="Gray" Height="500">
<table id="tblImages" runat="server" width="100%">
<tr>
<td>
<asp:FileUpload ID="FileUpload1" runat="server" />
</td>
</tr>
<tr>
<td align="right" width="100">
<asp:ImageButton ID="imbAddImage" runat="server" ImageUrl="images/plus.png"
Width="48" Height="48" OnClick="imbAddImage_Click"/>
</td>
</tr>
</table>
</asp:Panel>
This is code on button click
protected void imbAddImage_Click(object sender, ImageClickEventArgs e)
{
System.Web.UI.HtmlControls.HtmlTable tbl = (System.Web.UI.HtmlControls.HtmlTable)this.FindControl("tblImages");
System.Web.UI.HtmlControls.HtmlTableRow row = new System.Web.UI.HtmlControls.HtmlTableRow();
System.Web.UI.HtmlControls.HtmlTableCell cell = new System.Web.UI.HtmlControls.HtmlTableCell();
FileUpload temp = new FileUpload();
cell.Controls.Add(temp);
row.Controls.Add(cell); ;
int a=tbl.Controls.Count;
tbl.Controls.AddAt(a-1, row);
}
But problem is that a is always 2. Can anybody help ?
When it comes to dynamic controls, you need to add them on every post back.
You click event handler only adds the newest file and you are not saving the previous ones anywhere. You should add them to the ViewState and query the ViewState to retrieve them.
See this article For a detailed explanation of ViewState.

Asp.Net ListView how to delete a row without deleting from datasource

Through CommandName="Delete" I try to delete a line from the ListView control but not from the datasource. On Pressing Delete I expect the webpage to reload and show me the updated ListView(with one line deleted). But nothing changes, the ListView will display the same content after pressing Delete. What do I do wrong?
<asp:ListView ID="ListView1"
DataSourceID="XmlDataSource1"
ItemContainerId="DataSection"
runat="server">
<LayoutTemplate>
<h3>Protocols to Upload...</h3>
<table border=0 style="background-color:#9C9EFF; width: 100%;">
<tr align=left>
<th>Region/Exam/Program</th><th>Protocol</th><th>Position</th>
</tr>
<asp:PlaceHolder ID="itemPlaceholder" runat="server"></asp:PlaceHolder>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td><%#XPath("Location/Path")%></td>
<td><%#XPath("Location/Name")%></td>
<td><%#XPath("Location/Position")%></td>
<td style="width:40px">
<asp:LinkButton ID="SelectCategoryButton" runat="server" Text="Select" CommandName="Select"/>
</td>
</tr>
</ItemTemplate>
<SelectedItemTemplate>
<tr id="Tr1" runat="server" style="background-color:#F7F3FF">
<td><%#XPath("Location/Path")%></td>
<td><%#XPath("Location/Name")%></td>
<td><%#XPath("Location/Position")%></td>
<td style="width:40px">
<asp:LinkButton runat="server" ID="SelectCategoryButton" Text="Delete" CommandName="Delete" />
</td>
</tr>
</SelectedItemTemplate>
<%-- <ItemSeparatorTemplate>
<div style="height: 0px;border-top:dashed 1px #ff0000"></div>
</ItemSeparatorTemplate>--%>
</asp:ListView>
<asp:XmlDataSource ID="XmlDataSource1" XPath="HttpRequestBO/ProtocolsDTO/ProtocolDTO" runat="server"
DataFile="~/HttpRequestBo.Sample.xml"></asp:XmlDataSource>
And this is the code behind:
protected void Page_Load(object sender, EventArgs e)
{
}
protected void ListView1_OnItemDeleted(Object sender, ListViewDeletedEventArgs e)
{
if (e.Exception != null)
{
e.ExceptionHandled = true;
}
}
protected void ListView1_OnItemCommand(object sender, ListViewCommandEventArgs e)
{
if (String.Equals(e.CommandName, "Delete"))
{
ListViewDataItem dataItem = (ListViewDataItem)e.Item;
ListView1.Items.Remove(dataItem);
}
}
If I don't use the e.ExceptionHandled = true;, after pressing the Delete link the web page will come up with a "Specified method is not supported." message. Why?
If I use the above mentioned line, then the page refreshes but I can still see all original lines (although on debugging I can see that the ListVieItem collection now only contains an item less.)
It's because of the DatasourceID parameter, which binds at every single postback on the original file.
What you should do is to bind your list on the first page load only. The delete button will work as you expect then.
--- after comments.
OK.
In fact, the Delete command would work if you had defined the Delete method on your datasource. Since that's not what you want, you must define the ItemCommand event handler
and tell it to remove the ListViewItem that issued the event.
protected void yourListView_OnItemCommand(object sender, ListViewCommandEventArgs e)
{
if (String.Equals(e.CommandName, "Delete"))
{
ListViewDataItem dataItem = (ListViewDataItem)e.Item;
yourListView.Items.Remove(dataItem);
}
}
It will do so without touching the XML file beneath. Do not databind against it, else the "deleted" row will appear again.

Resources