Unable to update label in update panel from user control ASP.net - asp.net

My code is as follows.
<div class="table">
<asp:UpdatePanel runat="server" ID="labelPanel" UpdateMode="Conditional" >
<ContentTemplate>
<asp:Label Text="" runat="server" ID="Cost"></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
<uc1:ucPartsListing ID="ucPartsListing" runat="server" />
</div>
Now the usercontrol ucPartsListing itself has 2 update panels. There is an event fired from the user control to parent aspx for some conditions.
In that event, I am trying to set the label value which is present in aspx file. I am calling update manually from code-behind. Yet it doesn't work. Where am I going wrong ?
public partial class PartsEnquiry : BaseAuthPage
{
protected void Page_Load(object sender, EventArgs e)
{
ucPartsListing.OnQuotePartsItemSelect += new ascx.ucPartsListing.QuotePartsItemEventHandler(ucPartsListing_OnQuotePartsItemSelect);
}
void ucPartsListing_OnQuotePartsItemSelect(string price)
{
Cost.Text = price; //This is not working !
labelPanel.Update();
}

Set a breakpoint on your "void ucPartsListing_OnQuotePartsItemSelect(string price)" method and see if it gets hit at all.
I'm not sure what the user control is that you are using, but whatever control it is that is supposed to fire the event, try setting its AutoPostBack property to True.

I think you are out of luck with your current structure.
When the UpdatePanel inside you user control is fired in the browser, it will update the part of the page that is inside itself. You cannot update controls that are outside of the executing UpdatePanel.
Manually calling the Update() method on the outer UpdatePanel will not help since on the client it is still one of the inner UpdatePanels that is receiving the output back and updating the html tree.
To get it to work you will have to somehow trigger the outer UpdatePanel which will be able to update the Cost label.

Related

How to set focus back to control that originated postback

To avoid unwarranted "duplicate" flagging, let me say upfront - I have searched high and low for an answer and only found ones like this, which has no answer, or this, which tells me to use MyControl.Focus(); from my code behind. That does not work properly. I will explain.
I have a series of dropdown controls in an update panel, each of which affects the ones after it - City, Building and Room. When the user changes the selection in the city dropdown, mouse or keyboard, focus is immediately lost as the page does the partial postback. Ok, so I try to put in the CityListDropDown.Focus();, but that causes the page to reposition itself so that this control is at the bottom of the visible area of the page - not the desired behavior. The page should not move at all. Mind you, this only matters if you have a lot of other stuff on the page before your update panel, so that these prompts are lower down where the page has had to scroll down to them.
So, how do I restore focus back to that city drop down so when the user is using the keyboard, they can just keep on trucking to the next prompt? Same goes for the building drop down.
Here is my html:
<asp:UpdatePanel ID="RoomsUpdatePanel" runat="server" UpdateMode="Conditional" RenderMode="Inline">
<ContentTemplate>
<asp:DropDownList ID="CityListDropDown" runat="server" class="form-control input-sm" Width="140" AutoPostBack="True" OnSelectedIndexChanged="CityListDropDown_SelectedIndexChanged">
</asp:DropDownList>
<asp:DropDownList ID="BuildingListDropDown" runat="server" class="form-control input-sm" AutoPostBack="True" Width="100" OnSelectedIndexChanged="BuildingListDropDown_SelectedIndexChanged">
</asp:DropDownList>
<asp:DropDownList ID="RoomListDropDown" runat="server" class="form-control input-sm" AutoPostBack="False" Width="175">
</asp:DropDownList>
</ContentTemplate>
</asp:UpdatePanel>
and here is my code behind:
protected void CityListDropDown_SelectedIndexChanged(object sender, EventArgs e)
{
LoadBuildingList();
LoadRoomList();
CityListDropDown.Focus();
}
protected void BuildingListDropDown_SelectedIndexChanged(object sender, EventArgs e)
{
LoadRoomList();
BuildingListDropDown.Focus();
}
If you don't want the page to scroll / get repositioned whenever the focus is changed, you can use the PageMaintainScrollPositionOnPostback property of the Page directive :
<%# PageMaintainScrollPositionOnPostback="true" ... %>
or you can try setting it programatically through code :
Page.MaintainScrollPositionOnPostBack = true;
I got it! So using the code behind Focus() method of the control causes the page to reposition itself, even when you have set the MaintainScrollPositionOnPostBack property of the page to true. But, javascript can change focus without moving the page around unnecessarily. So if I need to reset focus from my code behind, to the sending control, I can do this:
protected void CityListDropDown_SelectedIndexChanged(object sender, EventArgs e)
{
LoadBuildingList();
LoadRoomList();
ScriptManager.RegisterStartupScript(CityListDropDown, CityListDropDown.GetType(), "CityDropDownRefocus", "document.getElementById(\"" + CityListDropDown.ClientID + "\").focus();", true);
}
or, if I want that line of code that resets the focus to be more generic (say I have an event handler that is used by multiple controls, and I need the handler to reset focus to the control that generated the postback, the handler is going to get the sending object, so I can say:
protected void MyControlHandler(object sender, EventArgs e)
{
...
ScriptManager.RegisterStartupScript((WebControl)sender, sender.GetType(), "CityDropDownRefocus", "document.getElementById(\"" + ((WebControl)sender).ClientID + "\").focus();", true);
}
And that resets the focus back to the sending control, without moving the page around!

Ajaxfileupload not working when dropdownlist is place inside an updatepanel in ASP.NET

When the page is loaded I have no problem using the ajaxfileupload and selecting files for the upload.
This works perfectly until I select a value of the first dropdownlist and the second dropdownlist inside the updatepanel gets populated via the partial postback. From this event on, the select button of the ajaxfileupload control is without function.
Is this a bug or how to overcome this issue?
set the dropdown's ID in PostBackTrigger of the update panel.
update:
<UpdatePanel ID="upd1">
<asp:DropDownList ID="ddl1" onselectedIndexChanged="ddl_changed" />
</UpdatePanel>
<UpdatePanel ID="upd2">
<Ajax:FileUploader />
</UpdatePanel>
protected void ddl1_changed(object sender, EventArgs e)
{
//your code
upd2.Update();
}
This might help you :)

Why do my dynamically added controls loose their values after Postback?

To ask my question I have created an aspx file containing a Button and a DataList with an SqlDataSource:
<asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
<asp:DataList ID="DataList1" runat="server" DataKeyField="a"
DataSourceID="SqlDataSource1" >
<ItemTemplate>
a:
<asp:Label ID="aLabel" runat="server" Text='<%# Eval("a") %>' />
<br />
b:
<asp:Label ID="bLabel" runat="server" Text='<%# Eval("b") %>' />
<br />
</ItemTemplate>
</asp:DataList>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:probaConnectionString %>"
SelectCommand="SELECT [a], [b] FROM [PROBA_TABLE]"></asp:SqlDataSource>
In my code behind I add TextBoxes to the Items of the DataList. I add to every Item a TextBox in the Page_Load, and another TextBox in the Button Click eventhandler as well.
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
foreach (DataListItem item in DataList1.Items)
{
item.Controls.Add(new TextBox());
}
}
}
protected void Button1_Click(object sender, EventArgs e)
{
foreach (DataListItem item in DataList1.Items)
{
item.Controls.Add(new TextBox());
}
}
}
}
This works fine except one thing. When I click the Button, the TextBoxes which were created in the Page_Load keep their Text value, but the TextBoxes which were created in the Button1_Click lose their Text values. My real problem is more complicated than this, but I think solving this would help me a lot.
Each control that should receive data from page ViewState should be instantiated in Init or Load event handlers, because ViewState is persisted to controls BEFORE Click, Change and the rest control events (those events are triggered when ViewState changes are detected, so ViewState must be read before Click event is fired).
So the process should look like:
OnInit (static controls get created)
Static control content is deserialized from ViewState
OnLoad (create dynamic controls, in your case textboxes that you created in last Postback)
Dynamic control content is deserialized from ViewState
Click, Change and other events are fired according to changes detected comparing POST data and ViewState data
Suggestions:
You can use hidden fields to save additional status information, and then in OnLoad you can read that info to recreate dynamically created controls.
Also, you should explicitly set ID property of your textboxes so that values can be properly persisted back, don't rely on ASP.Net.
the http by default is stateless that means after your request is processed the server keeps no data or info of the request
but the values in the form need to be persisted in special cases when there is an error
suppose you fill up a long form and then post it back to the server only to get an error message and all the filled up values are gone. wouldn't that be annoying
so what asp.net does behind the scenes that it keeps a string in the page hidden that has information about all the server controls and their ids
so when you post a form back the Page class is created and the values that are posted back and binded in the specific controls because the Page class is being created in every request the pageLoad event is run and controls created in the PageLoad are then present values corresponding to their ids are put into them unlike the controls that are being created on button click till the button_click event is run that viewstate has already been deseralized and values are filled into them

Controls within .ascx are not displaying their new value on postback

This seems like an elementary issue but it has me stumped.
I have a main page which loads a custom control (.ascx) on page_load.
This custom control has two fields. One of them being a dropdownlist and the other being a text box. When the dropdownlist changes value it triggers a post back, some logic is executed server side and a value is generated for the textbox. I stepped through the code and the value is created and assigned correctly. However, when the page is rendered the value does not change.
If I change the textbox value to "QQQ" and trigger the postback, "QQQ" stays in the textbox so I can verify viewstate is working.
Is there any reason why the generated value is not being displayed in the form on postback. This process works fine on the initial page load.
.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
string ascxPath = #"~/_CONTROLTEMPLATES/TRC_BITS.ascx";
TRC_BITS control = Page.LoadControl(ascxPath) as TRC_BITS;
phForm.Controls.Add(control);
}
.ascx
<asp:TextBox ID="message" runat="server" TextMode="MultiLine" /><br/>
<asp:DropDownList ID="year" runat="server" AutoPostBack="true">
<asp:ListItem Text="2011">2011</asp:ListItem>
<asp:ListItem Text="2012">2012</asp:ListItem>
<asp:ListItem Text="2013">2013</asp:ListItem>
</asp:DropDownList>
.ascx.cs
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
year.SelectedValue = DateTime.Now.Year.ToString();
}
if (year.SelectedValue == 2012)
message.Text = "ABC";
else
message.Text = "XYZ";
}
Because you're adding these controls to the page dynamically, you need to assign an ID to the user control. Make sure to assign the same ID to the controls every time the page is posted back, and the fields will be repopulated from ViewState.
Also, as Shai suggested, it would be more appropriate if you loaded the controls during OnInit instead of Page_Load. The situation is a little different with user controls, but in general you want to add your dynamic content before the LoadViewState method is executed.
If you're looking for something to take the pain out of persisting dynamic content, I would suggest taking a look at the DynamicControlsPlaceHolder.
Because you are adding the controls dynamically, you need to add them during the page's oninit event.
Try it, believe me. Go for it. Yalla.

Why aren't all controls initialised at the event handling point of the ASP.NET page lifecycle?

I have a user control embedded in a web part. It has the following snippets of code:
protected TextBox searchTextBox;
protected Button goButton;
protected Button nextButton;
protected Repeater pushpins;
protected Label currentPageLabel;
protected void goButton_Click(object sender, EventArgs e)
{
// Do stuff
}
<asp:TextBox ID="searchTextBox" runat="server" />
<asp:Button ID="goButton" runat="server" Text="Go" OnClick="goButton_Click" />
<asp:Repeater ID="pushpins" runat="server" EnableViewState="false">
<ItemTemplate>Blah</ItemTemplate>
</asp:Repeater>
<asp:Label ID="currentPageLabel" runat="server" />
<asp:Button ID="nextButton" runat="server" Text=" >> " OnClick="nextButton_Click" />
(There is no OnLoad or CreateChildControls method.)
If I place a breakpoint on the first line of goButton_Click, I find:
searchTextBox: initialised
goButton: initialised
nextButton: NULL
pushpins: initialised
currentPageLabel: NULL
Why are some controls initialised and others not? How do I get around this if I'd like to update the Text property on currentPageLabel?
Update:
I've placed breakpoints all the way through the page life cycle and found that nextButton and currentPageLabel are never initialised. The breakpoints were placed at OnLoad, CreateChildControls, goButton_Click, OnPreRender, Render and OnUnload.
Is it possible you've inadvertently got local variables named currentPageLabel and/or nextButton declared somewhere? The compiler will happily allow this...
This is especially common in a move from ASP.NET 1.1 to 2.0 or higher, since the way the designer defined these controls changed.
The problem was that all of the controls that weren't being initialised were inside a HeaderTemplate within a Repeater control. (To save space I didn't paste all of my code into the question, dang it.)
I moved them out and the problem is resolved. Obviously controls in the HeaderTemplate are instantiated by the Repeater and do not follow the normal page life cycle.

Resources