Here is what I have
A set of business entities that resides in the session (for example, Employee:{"Name":string,"Surname":string,"Salary":double, "Position":enum}
A set of user controls (using Telerik.Web.UI), each of it describing a business entity (for example, EmployeeControl.ascx:
RadTextBoxes for Name, Surname and Salary and a RadComboBox for Position. There is also a RadButton in the control, which saves the data that is entered in the controls client-side to a certain entity, which is already known by the time the control is loaded).
A page with a RadTabStrip and RadMultiPage, which is used to render different controls in different tabs
The target RadTab that hosts our Employee control.
So, the issue is: when I hit the Save button, a postback is done, thus clearing my controls and only after that the Click event is fired. I have tried to avoid it by using RadAjaxManager with a OnClientClicking script with canceling the postback, but with no success, because a postback is still generated, although its __EVENTTARGET is RadAjaxManager itself.
Basically, this is what happens:
The user selects a tab with the Employee control with it. The control is filled with initial data on Page_Load. (A postback occurs with re-creating my controls)
The user modifies the data. (Nothing happens, no control generates postback)
The user clicks save. (A postback occurs with re-creating my controls, then a Click event is fired)
No data is saved
When the data is entered again and the save is called, everything is saved as it should.
How can I make this work correctly?
P.S. I was able to achieve the required result (although not completely: the screen "flickers" when a postback is done) by dividing the postbacks into odd ones and even ones (I added another variable in Session named PostCounter, which is incremented every time the page is posted). So, when an expression PostCounter % 2 is equal to 0, I perform another postback by executing __doPostback with its eventTarget parameter being the ClientID of an instance of a RadAjaxManagerProxy, and the argument being just some string that does not match any that is used in my regular Ajax requests.
Make sure your controls always have the same IDs when recreated. Imitating postbacks from other controls should not be needed, the buttons are IPostBack controls so things should work nicely.
This (one AJAX, one full postback) behavior is typical for Sharepoint where you need to add AJAX settings programmatically: http://www.telerik.com/forums/radajaxmanager-in-webpart-on-sharepoint-2010
Also, make sure you do not nest AJAX settings (from a manager and/or proxy), RadAjaxPanels and asp:UpdatePanels: http://www.telerik.com/help/aspnet-ajax/ajax-controls-in-ajaxpanel-and-ajaxsettings.html.
Related
I have an aspx/WebForms page that includes a user control. This user control contains, among other things, a Repeater that forms a UI for a user to input a variety of things. The three most notable things in this repeater are a CheckBox, a DropDownList, and a TextBox. There are an arbitrary number of lines in the repeater - it could be 0, could be 15. Depends on the user.
I am able to retrieve data from my database and bind the data to the Repeater just fine. The user control functions as it should during the main interaction time.
The problem arises when it comes time to recover the data the user has now edited. Whether I use a component inside the user control or in the user control's parent page to cause a postback, the first whiff I get of the user control (in the parent page's OnInit) has re-created the user control and obliterated the data the user has input. I have tried everything I can think of to get at the post back data, but it all turns out the same - by the time the WebForms give me any visibility to the data, it's gone.
How can I retrieve the modified data from the user control, without losing it to the parent page's templating system's overwrite?
About 5 months ago I was tasked with creating a new intranet site for my current employer as the old one is a nightmare to work with. The site uses multiple .NET languages (classic asp, VB, and C#) with multiple .NET frameworks (1.0, 2.0, 3.5, few places with 4.0). Simple changes that should only take an hour to implement and test would take days just to implement.
The new intranet sites content is controlled through user controls that are loaded dynamically at load time based on the page you are on and the access level you have. Each user control has a specific task and does not affect any other user control on the page.
About 3 weeks ago my database guy (was an application developer at his last job) pitched this idea to the middle management that the user controls could talk to each other and affect the selections available in each user control (all this without my knowledge).
At first, I didn't think it was possible when I heard. Then, everything I read about having user controls communicate with each other indicated that the user controls had to know about each other and that wasn't possible since all of the user controls are load at runtime based off of the access level you have. I found a solution last week were I could have a user control fire a custom event handler and have my other user controls listen for that specific custom event handler.
Now, today, I was asked if I could add filtering to the contact management part of the site that lists all of our clients similar to how Ebay has there filters on the left that allows you to drill down farther into the results returned. For example, you search "flat screen tvs". Ebay will list all results that match you search and on the left you can select the size range or the brands to narrow down the results.
On the page I setup I load 3 user controls to handle the criteria and the results. Control1 has all of the basic search criteria (ex. industry, region state, ect), control2 has the filters for drilling down the results from control1. Control3 displays the clients based off the criteria in control1 (so control1 fires an event that control2 and control3 hear and they both display the results based on control1). Now I select the criteria from control2 and fire the event that control3 can hear and displays the results.
All of this works, the problem I am having is that the controls in control2 are built dynamically and when the event in control1 is fired -> then control2 posts back to fire the event for control3 to hear I lose all the dynamic controls in control2 as the controls can't be recreated in the Page_Init because the values passed in from the custom event in control1 no longer exists because control2 did the postback and the event from control1 is only fired when control1 postsback. What is the best way to store the values passed in to control2 from control1's custom event or get control1 to repass the values when control2 posts-back so I can recreate the dynamic controls in control2?
Note: I tried using sessions but had trouble reassigning values from control1 after the first search. I believe the reason they don't work is due to the way I have control1 setup and the creation of dynamic controls in control2 is skipping over getting the session values.
I thank all of you in advance for your (hopefully) helpful responses.
Update
Turns out that the way I was loading my usercontrols at runtime on my default page is the reason why the dynamic control in 'control2' were not being recreated when 'control2' posted back. My default page loaded the usercontrols in the 'page_load' instead of the 'page_init' (must have forgot to move the loading of usercontrol to the 'page_init' like all my other pages). Made the switch and the dynamic controls are recreated on postback.
The only issue that I had after moving my code from the 'page_load' to the 'page_init' was that the 'checkbox' controls would be unchecked on postback even though I checked them. I was able to over come this with a few session variables.
This is a common problem.
Only controls dynamically created in your page_init event can survive a postback.
During page_init, dynamically created controls become part of the DOM, and thereby have sessionstates. If you can re-factor your code to fire the dynamic control creation during page_init, your controls should survive.
Update:
I realize from your comments and post that you're reluctant to use Sessions. Problem is that Sessions are the ONLY way to save your controls.
One way I dealt with this case was to create a Class Object with Lists of Controls. When I came back to the page, if the Object existed I used it as a default.
Second way I approached this was to save the search criteria in Session and feed the criteria to my dynamic control creation method.
OK, got pretty far on this one, but need an assist from someone with superior ASP skills. I'm using code behind to populate an ASP table with the results of a SQL query. The read-only values are stored in the .text of some of the table cells, while read-write values are stored in .text of textbox controls (dynamically created and added to table cells.)
This works fine on the first load. When the page reloads with a different query (for example: a user selects a different column to order by,) the table cell values repopulate correctly, while the textbox values remain unchanged. Throwing in a table.rows.clear() prior to the query does not seem to fix this.
More info:
I created a method to wipe all textbox.text values using table.findcontrol(). When tied to a button, this method works to spec (which indicates findcontrol is able to find/update the textboxes,) though all affected textboxes remain the blank if the page is reloaded. If placed in the page load, the method does nothing (textboxes retain their former values.) In debug mode, findcontrol pulls a value when used on the button, but comes up null when added to pageload. I have done this with table.rows.clear() commented and uncommented.
I have also attempted to throw all the code into oninit. This doesn't seem to make any appreciable difference.
Dynamic controls must be added on each page request, preferably during the Init event. It sounds like you are not recreating them on time.
Add them on every single page request and, as part of the page life cycle, they will receive their values from the viewstate
In order for dynamic controls to retain their values you need to:
a.) Ensure Viewstate is enabled for the page.
b.) Recreate the controls on every page load ensuring you create the controls with the same IDs as were given to the controls originally. Also you need to do this before the viewstate is loaded (preferbly in the Onit or PreInit method. See the page life cycle here: http://msdn.microsoft.com/en-us/library/ms178472%28v=vs.100%29.aspx
I am dynamically loading user controls to switch between views in my project. I am aware that I need to reload my user control on every postback. The odd thing is my viewstate for the control is maintained even though the control is gone? I confirm that the panel I loaded it into is empty and then I check the view state and my value is there.
What's stranger is that if I load a different control, it can see the viewstate from the previous control? I checked and my page cannot see viewstate from my dynamically loaded control and visa versa. This makes me think the user control is treated as its own page. The confusing part is why the second view I load can see values from the first and why the values are there even though I the control has disappeared?
I also find this section of the code to be useless. Why is it removing the control? The panel is always empty (the code is from Telerik):
string controlId = LatestLoadedControlName.Split('.')[0];
Control previousControl = pnlControlPlaceholder.FindControl(controlId);
if (!Object.Equals(previousControl, null))
{
this.pnlControlPlaceholder.Controls.Remove(previousControl);
}
I looked at several posts and most say that viewstate is lost on every postback, although this is not the case for me. Perhaps because I'm using update panels. Although if an intial request handles an event and then reloads the same control again, the viewstate is lost. It only seems to preserve the viewstate on the very next postback.
Can anyone explain this odd behavior of sharing viewstate between user controls or why it is there even though the control is lost?
Apparently you can read viewstate between pages in two scenarios... Cross page postback and when using Server.Transfer. I believe the cross page postback scenario would explain what I am seeing.
I have a Web User Control that I need to add to a page simply in order to add it to an HtmlForm so I can send an email with this User Control, however, I do not need this Control to appear on the page, I just need it to fill with data so I can send this email, and then be removed so it does not appear on the page.
Currently I have tried:
myControl c = new myControl();
c.InitializeAsUserControl(Page);
c.fillInfo(data);
//add to email form and send email
yet this adds the control to the current page on post back once the email has been sent and a confirmation message
I have also tried
myControl c = (myControl)Page.LoadControl("~/filename.ascx");
//send email
Page.Controls.Remove(c);
yet this also renders the control on the page and does not remove it. I have tried to add it to a panel and set Visible to false, but unfortunately this does not work either. If I simply create a new myControl() without rendering on page or calling LoadControl I get exceptions thrown when fillInfo is called when it tries to modify asp:labels in the User Control saying that the objects are null or not instantiated.
Which part of the page cycle are you loading and unloading the controls? To work properly it needs to be done in Page_Init. It's a common mistake to do it in Page_Load. If it is added anywhere else other than Page_Init it won't be added to the ViewState correctly and problems will ensue.
Rather than unload - I would add it to a Panel and set Visibility to false. Could be the reason that isn't working for you at the moment is that the control is being added at the wrong part of the page cycle and isn't being added to ViewState correctly.
Could that be your problem?
I suggest reading the entire TRULY UNDERSTANDING DYNAMIC CONTROLS series. To successfully use dynamic controls with postbacks, viewstate, bindings, and the other WebForms features, you really have to know the page and control lifecycles and their interactions inside out.
When you load and set ViewState depends on the cycle. ViewState is loaded between Page_Init and Page_Load, so the control has to be in Page_Init. However, any processing based on auto-loaded ViewState, needs to go in Page_Load. Where/when ViewState is enabled depending on the control hierarchy can also affect this. I suggest you read that guide above in depth if you really want it to work. Or, you'll have to post your entire control code and its use in a page for us to tell you which parts you are missing or have in the wrong part of the page lifecycle.
I've made dynamic controls work, but 99% of the time, unless the control is extremely trivial, it's easier to find a different solution than it is to make sure all the interactions work correctly with dynamic control creation.