SharePoint Simple WebPart Lifecycle - asp.net

I am trying (and failing) to get a very simple webpart working.
button which when pressed adds list item into custom list (this works great)
list out all the items from the custom list (this also works great)
the problem is that when i display the items and add a new item i need to refresh twice to get the listing to display the item that i am trying to display. What is the correct lifecycle that i need to follow with createchildcontrols, onload etc so that when i click the button and it adds a record in that the listing will display the newly inserted item.
Thanks

This is probably a case of setting the control values or forcing databinding in OnLoad; this is before the "add item" occurs which is before the new item has been added.
I recommend using Data-Binding expressions and ensuring databinding in PreRender1. As long all the controls follow this later-databinding it should Just Work. Otherwise, manually force update/databind the appropriate controls after (or in response to) the "add item" action.
The Life Cycle is the same as for ASP.NET WebForms, and summarized for the issue:
- "OnLoad"
- PostBack Actions such as "OnClick"
- "PreRender"
1 Databinding in PreRender works - even though it initially seems like it ought not to - because ASP.Net controls will Catch-Up as required.

Related

Create Dynamic Controls using retrieved data [Asp - Vb .Net]

I'm trying to create multiple controls by using retrieved data from query, but preventing them from dissapearing on postback, allowing me to get and mantain their values, the problem I have is that I cannot create them on Init because the number of controls, their IDs, and other properties are only known after user selects an item on menu.
Page loads a Menu with all its items and values (Data dependent), plus, a button is loaded too
User clicks a item on menu.
Selected value is used to perform a query by using a Dataset (This happens inside a function which is called from Menu_ItemClick event).
Retrieved data from query is used to determine how many controls must be created (2, 4, 6, etc.). Each control has its unique ID, which is given according to data.
Controls are created and placed into a Panel (named p).
Now controls are visible and available for editing (RadioButtons, TextAreas)
User clicks on button to save information from dynamic controls into a Database
Problems I'm facing
Controls dissapear on postback when clicking button, because they weren't created on Init.
Placing button on UpdatePanel to prevent whole page postback, makes dynamic controls not accesible when trying this:
For Each c In p.Controls
...
Next
The only control it gets is a single Literal control (Controls count is 1), as if other controls didn't exist.
Thank you in advance.
When you wrote "Controls dissapear on postback when clicking button, because they weren't created on Init", did you mean to say that "Controls dissapear on postback when clicking button, because they weren't re-created on Init"? If not, then that is likely a root cause of your problem - dynamically-created controls must always be recreated in response to a PostBack (cf. ASP.NET dynamically created controls and Postback). There may be other issues as well, as dynamic controls in Web Forms can provide a lot of challenges as your scenario gets more involved - here's one article that lays out many of them under various scenarios http://www.singingeels.com/Articles/Dynamically_Created_Controls_in_ASPNET.aspx (e.g., if the user can re-select from the DropDownList to generate a different set of dynamic controls). The canonical reference on all of this is http://msdn.microsoft.com/en-us/library/ms178472.aspx.
Now, on PostBack you'll need some way to ascertain which controls were dynamically created so they can be dynamically re-created. As such, you'll need to store somewhere whatever information allowed you to dynamically create the controls. Since ViewState isn't available in Page_Init and there can be other issues introduced when using sessions, my suggestion is to simply declare a HiddenField that contains that state information. In Page_Init, you'll then need to get the HiddenField's value from Request.Form (since the value of your HiddenField won't be loaded until after Page_Init from ViewState) and go from there to re-create your controls.
My final suggestion: try getting everything working with a regular Panel first and then try and introduce the UpdatePanel - no need to over-complicate the problem at first.

LinkButton in update panel does not even fire client side event

I have a page that if IsPostBack is true, calls a javascript function which gets the size of the screen, passes the width and height to hidden fields and clicks a button to cause a PostBack. So I can retrieve the size of the user's screen and then load the page with default data with tables the right size etc.
Invariably, when the page (having posted back once) displays the data, a gridview is populated. Each row has a 'delete' Link Button in it. Each Link Button is set OnClientClick to call a javascript function to confirm you want to delete.
Above the grid is a row of text boxes / buttons / dropdownlists which allow you to search for, or filter the data showing. The Gridview is in an update panel. When the page first loads its data, and shows the list of projects, the delete Link Buttons all work okay. In every row, no problem. The Confirm box is displayed and, if Okay is selected, the asynchronous postback occurs.
If, after the initial data is displayed (which is already after one postback) you then use the search box and button, or use a dropdownlist to filter the data (the Search button and filter DropDownList are async triggers for the UpdatePanel) the data refreshes okay (always) but, then, sometimes, the 'delete' LinkButton in each row of the GridView does nothing. It doesn't even fire the ClientSide function. It's as if it is dead.
I had a similar problem a while ago with ImageButtons and the received wisdom seems to be 'change them to LinkButtons'. But I have dozens of grids with 'delete' LinkButtons that work okay, but this one has decided to stop working - sometimes.
I have to say, since moving to Framework 4.0, I'm thinking of giving up on UpdatePanels. Seem to have nothing but problems with sites that worked reliably for years in Framework 2.0
Any ideas please? Is this anything to do with the order in which controls are loaded on the second postbacks?
Edit: There is a twist to this. When this situation occurs, i.e. clicking on the Delete link does not even trigger the Client Side event - if you click on an area of the page outside the Gridview (i.e. outside the UpdatePanel) - and then click back on the Delete link - it works!
Regarding ImageButtons: There is a bug with IE10: ASP.NET fails to detect IE10 causing _doPostBack is undefined JavaScript error or maintain FF5 scrollbar position ( http://www.hanselman.com/blog/BugAndFixASPNETFailsToDetectIE10CausingDoPostBackIsUndefinedJavaScriptErrorOrMaintainFF5ScrollbarPosition.aspx ). Just upgrade to .NET 4.5.
Regarding LinkButtons: Do you have "ID" property? I remember I had a similar issue because my linkButton didn't have an ID.
Could you post some code? It would help.

Dynamically generated Radio Button calling CheckedChanged event

This is a little difficult to explain so please bear with me.
I have a procedure that is generating some radio buttons and assigning a CheckedChanged postback event based on the level being passed through (up to 4 levels). When the first level is checked (radio button selected) the postback event rb_CheckChanged00() is called and a check is done to see if this item has any children, if it does, it will create more radio buttons and assign rb_CheckChanged01 to the CheckChanged event for these - This part is working fine.
The issue I have is when I select the second Radio Button that has been created (the child), it doesn't seem to go to the post back event at all. The page is posting back when I click on it but everything resets because it won't go into rb_CheckChanged01.
I know this info is quite vague but I am hoping someone has an idea on how the post back event works and if I am somehow using it incorrectly.
Using: ASP.NET 2.0, IIS7
Thanks.
Most of the time when the dynamically created control's events are not fired, it's because the controls are 'reset' upon postback.
To make sure the same controls get created each and every time make sure that the control's IDs are set to the same values each and every time, before the ViewState is loaded. This way, when the control is added to the control collection of the page, once the ViewState is loaded, it'll persist it's properties. (just to describe what happens, in a nutshell)
One of the best articles I've read on this topic is this one. Make sure you read it, to fully understand what's happening in the background.
Looks like the child RBs are cleaned before they are able to trigger the event. From my personal experience, it's best to keep track of those dynamically generated objects, and regenerate them in every postback. The events will start to trigger :)
Your controls and events are not registered in the ViewState because dynamic controls need to be loaded in the Page_Init. Because they're not persisted in the ViewState, they won't be registered with events. A similar question:
Problem with dynamic controls in .NET
Only 1 thing can cause this, you create the rb's on page_load and don't add them to a List<> or something similar and that object to Session. What you need to do is when you create the items, Add them to a List and add that list to Session["RadioButtons"] and if the Page.IsPostBack is true, load your controls one by one from your list which is kept in your session to your page.

Passing data to server code from a client-side control using ASP.NET AJAX

I have a ListView on a page that displays a list of widgets. When a user clicks on one of the items in the list, I want to display a ModalPopup that contains controls allowing the user to operate on the item they selected.
I could easily accomplish this by placing a Panel and a ModalPopupExtender in the ListView's ItemTemplate, but this mean one set of hidden controls for each and every widget, which would massively bloat the page size. (There are going to be some rather heavyweight controls in there.) Instead I want to reuse a single ModalPopup for each of the widgets in the list.
I've done some searching but I haven't found anything that applies directly to my situation before. From what I've been able to figure out, however, I have to do something like this:
Place a Panel and a ModalPopupExtender on the page inside an UpdatePanel.
Build a custom WidgetManipulator user control that has a WidgetID property. Put this in the Panel, along with a couple OK/Cancel buttons.
In Javascript on the page, attach a click handler to each widget in the ListView that triggers a postback on the UpdatePanel.
On the UpdatePanel_Load event on the server, display the ModalPopup and then set the WidgetID propety on the WidgetManipulator to the ID of the clicked widget.
On the OKButton_Click event or CancelButton_Click event on the server, hide the ModalPopup. If OKButton was clicked, call WidgetManipulator.SaveChanges() first.
The part I haven't figured out is: How the heck do I know what widget was clicked on, and how do I pass that back to the server when I refresh the UpdatePanel? Is this even the right approach at all?
If you can use jQuery instead you could do something along the lines of these two posts:
Modal Delete Confirmation Version
Two Using jQuery SimpleModal Plugin
Demo
Inserting Content Using
jQuery SimpleModal Plugin Demo
When I need to pass data from client to server in ASP.NET AJAX, I generally use an asp:HiddenField with runat="server". Both can see it freely, but beware potential postback asynchronicity.
Sounds like you need to notify the server the widget was clicked - You may use a Timer to postback; or I'd go with option 5.

ASP.NET Dynamic Page Controls: Is it possible to bind events AFTER Page.Load?

I have a site that I am currently working on in ASP.NET 2.0 using the usual WebForm stuff and ASP.NET AJAX 1.0. Is it possible to bind an event to a dynamically created control after the Page.Load event?
I have a table <td> element that I am dynamically creating similarly to this code:
' Create Link Button
lnk.ID = String.Format("lnkDetails_{0}", dr("Id"))
lnk.Text = dr("Name").ToString()
lnk.CommandArgument = dr("Id").ToString()
AddHandler lnk.Click, AddressOf DetailsLink_Click
cName.Controls.Add(lnk)
This this code is looped over for each row in a database (and of course more cells are added to the table, including an ImageButton with an event. The events work flawlessly when I execute this code during events leading up to and including Page.Load. I need to be able to fill this table with current data, which is updated during a btnClick Event elsewhere on the page, which occurs after this Page_Load event, so I am populating with old data. If I change this code to Page.LoadComplete, events stop working.
This data is a summary display of various components of an application, things like somebody's name, which when updated on a 'detail' form, updates the database by partial postback (a requirement), then it needs to show the update in this 'summary' section after an update. Currently it takes 2 postbacks to actually see the change in the 'summary' section, so effectively the summary is 1 step behind the changes (clear as mud?)
What would be the best way for me to populate this table with current data (which is available during/after Page.LoadComplete), but still have an event fire when a link is clicked (the event causes an UpdatePanel to display the 'detail' form).
I also have jQuery at my disposal and the usual ASP.NET AJAX methods, also javascript is a requirement for the website, so I do not need to degrade for unsupported browsers.
This is my first ASP.NET web application and need some help figuring out the best way to make this happen (I'm well versed in PHP, Django and the usual ways to do web forms - things like having multiple forms on one page o_O).
Update:
There really isn't a good way to bind control events to controls after Page_Load. The overall architecture of the pages is there is one ASP.NET form encompassing the entire page, there is only 1 aspx page. I am using master pages (however it doesn't have any obvious implications to my issue).
The page is split into a left and right 'pane', the left is a summary of all the data (in an update panel), the right 'pane' has 6 'tabs' implemented each as their own user control, each with several form fields and an update button all in it's own UpdatePanel.
An update on any of these tabs only refreshes the summary panel (UpdatePanel.update()) and its own panel. The 'refreshing' and event binding of dynamic controls of the summary from the db happens during Page_Load and the Update Button event updates db data. (The control event happens after Page_Load). I want to avoid doing a double post to get the summary to update, any thoughts are helpful.
You need to postback the whole page after your data changes in the 'btnClick Event elsewhere on the page'. It sounds like you have an UpdatePanel and it sounds like this is catching the postback of your btnClick event handler. Put the btnClick outside the UpdatePanel or change its triggers so that your btnClick forces a postback/refresh of your data. Or, redesign your table so it's AJAXly-refreshed when you click on btnClick, it's hard to get you more details without knowing more about the structure of your page and controls.
Good luck!
You can bind to an event whenever you want. It's just a simple event after all. But not all places might be suitable because you have to take into account when the event fires. And in most cases this happens between Page_Load and Page_PreRender. That includes the click event on a LinkButton. In general, I would recommend to add your dynamically created controls in the Page_Init stage.
You have to add the controls before Page.Load in order to maintain ViewState between postbacks, so use the OnInit event handler for that.
But once they're added, you should be able to bind event handlers (such as OnClick) at any point during or after the Page.Load... for example in your grid's ItemDataBound (or something like) or in the Page.PreRender.

Resources