AsyncPostBackTrigger not firing on load of user control - asp.net

I have an update panel which refreshes a user control. The update panel is set to conditional, and the condition is on a textbox control. Using AsyncPostBackTrigger, to fire when the text changes in the textbox, it works fine. However, what I am not getting is when the page is first loaded, and the textbox is populated with data is that it is not firing the postback trigger.
Is there a way of forcing it fire when the page is loaded for the first time?
I have tried simple things such as UpdatePanel.Update(), or txtbox.text = string.empty to force it to recognise a change- but no luck.
Any ideas anyone?
Thanks

Please replace with your ids
private void tb_Loaded(object sender, RoutedEventArgs e)
{
TextStateChanged((TextBox)sender);
}
UpdateSite.txtPhone.Loaded += new RoutedEventHandler(tb_Loaded);

Related

Best way to allow postback on a gridview without viewstate

My gridview is basically a hit list of results from which the user selects one, and I want to get a postback saying which one he has selected. There is no need for the grid contents to survive the postback round-trip because the hit list disappears as soon as he has selected an item.
I don't want to use viewstate because the hit list is likely to be large. I don't want to databind from the database in PageLoad to repopulate the grid because the search may take a while.
what I'm thinking at the moment is that I can put some javascript on the 'select' link to store the ID of the selected item in a hidden field and then call __doPostBack
this still seems a bit clunky. can you think of a cleaner way?
If the postback should be triggered when the user clicks the anywhere in the row, use the ItemDataBound event to attach a client onclick handler:
protected void GridView1_ItemDataBound(object sender, GridViewRowEventArgs e)
{
var dataItem = e.Item as GridViewRow;
if (dataItem != null)
{
dataItem.Attributes["onclick"] = string.Format("__doPostBack(this, '{0}')", e.Row.RowIndex);
}
}
Is the ID of the selected item something sensitive that should not be seen by the user?
If it is not, you could just make your select button a link to the next page, with the ID as a querystring variable. Clicking would just move to the next page, no postback required.

ASP.NET: Postback processed without events being fired

I have a GridView with dynamically created image buttons that should fire command events when clicked. The event handling basically works, except for the very first time a button is clicked. Then, the postback is processed, but the event is not fired.
I have tried to debug this, and it seems to me, that the code executed before and after the first click is exactly the same as for any other clicks. (With the exception that in the first click, the event handler is not called.)
There is some peculiarity in that: The buttons which fire the event are created dynamically through databinding, i.e. databinding must be carried out twice in the page lifecycle: Once on load, in order to make the buttons exist (otherwise, events could not be handled at all), and once before rendering in order to display the new data after the events have been processed.
I have read these posts but they wouldn't match my situation:
ASP.NET LinkButton OnClick Event Is Not Working On Home Page,
LinkButton not firing on production server,
ASP.NET Click() event doesn't fire on second postback
To the details:
The GridView contains image buttons in each row. The images of the buttons are databound. The rows are generated by GridView.DataBind(). To achieve this, I have used the TemplateField with a custom ItemTemplate implementation. The ItemTemplate's InstantiateIn method creates the ImageButton and assigns it the according event handler. Further, the image's DataBinding event is assigned a handler that retrieves the appropriate image based on the respective row's data.
The GridView is placed on a UserControl. The UserControl defines the event handlers for the GridView's events. The code roughly looks as follows:
private DataTable dataTable = new DataTable();
protected SPGridView grid;
protected override void OnLoad(EventArgs e)
{
DoDataBind(); // Creates the grid. This is essential in order for postback events to work.
}
protected override void Render(HtmlTextWriter writer)
{
DoDataBind();
base.Render(writer); // Renews the grid according to the latest changes
}
void ReadButton_Command(object sender, CommandEventArgs e)
{
ImageButton button = (ImageButton)sender;
GridViewRow viewRow = (GridViewRow)button.NamingContainer;
int rowIndex = viewRow.RowIndex;
// rowIndex is used to identify the row in which the button was clicked,
// since the control.ID is equal for all rows.
// [... some code to process the event ...]
}
private void DoDataBind()
{
// [... Some code to fill the dataTable ...]
grid.AutoGenerateColumns = false;
grid.Columns.Clear();
TemplateField templateField = new TemplateField();
templateField.HeaderText = "";
templateField.ItemTemplate = new MyItemTemplate(new CommandEventHandler(ReadButton_Command));
grid.Columns.Add(templateField);
grid.DataSource = this.dataTable.DefaultView;
grid.DataBind();
}
private class MyItemTemplate : ITemplate
{
private CommandEventHandler commandEventHandler;
public MyItemTemplate(CommandEventHandler commandEventHandler)
{
this.commandEventHandler = commandEventHandler;
}
public void InstantiateIn(Control container)
{
ImageButton imageButton = new ImageButton();
imageButton.ID = "btnRead";
imageButton.Command += commandEventHandler;
imageButton.DataBinding += new EventHandler(imageButton_DataBinding);
container.Controls.Add(imageButton);
}
void imageButton_DataBinding(object sender, EventArgs e)
{
// Code to get image URL
}
}
Just to repeat: At each lifecycle, first the OnLoad is executed, which generates the Grid with the ImageButtons. Then, the events are processed. Since the buttons are there, the events usually work. Afterwards, Render is called, which generates the Grid from scratch based upon the new data. This always works, except for the very first time the user clicks on an image button, although I have asserted that the grid and image buttons are also generated when the page is sent to the user for the first time.
Hope that someone can help me understand this or tell me a better solution for my situation.
A couple problems here. Number one, there is no IsPostBack check, which means you're databinding on every load... this is bound to cause some problems, including events not firing. Second, you are calling DoDataBind() twice on every load because you're calling it in OnLoad and Render. Why?
Bind the data ONCE... and then again in reaction to events (if needed).
Other issue... don't bind events to ImageButton in the template fields. This is generally not going to work. Use the ItemCommand event and CommandName/CommandArgument values.
Finally... one last question for you... have you done a comparison (windiff or other tool) on the HTML rendered by the entire page on the first load, and then subsequent loads? Are they EXACTLY the same? Or is there a slight difference... in a control name or PostBack reference?
Well I think the event dispatching happens after page load. In this case, its going to try to run against the controls created by your first data-binding attempt. This controls will have different IDs than when they are recreated later. I'd guess ASP.NET is trying to map the incoming events to a control, not finding a control, and then thats it.
I recommend taking captures of what is in the actual post.
ASP.NET is pretty crummy when it comes to event binding and dynamically created controls. Have fun.
Since in my opinion this is a partial answer, I re-post it this way:
If I use normal Buttons instead of ImageButtons (in the exact same place, i.e. still using MyItemTemplate but instantiating Button instead of ImageButton in "InstantiateIn", it works fine.
If I assert that DoDataBind() is always executed twice before sending the content to the client, it works fine with ImageButtons.
Still puzzled, but whatever...

ASP .Net Gridview rowupdated - can it happen before the page load?

Here's the scenario:
-Gridview control
-Calendar control
I only want the calendar to show if a specific item is chosen in the drop down list which is in a gridview. When the grid view row is updated I want to change whether or not the calendar is visible. The calendar's visibility only shows correctly on the next post back.
Page_Load is called before events which are called before Render. There is no reason why you couldn't, in your event, check the value of the dropdownlist and set the Calendar control visible property, this would then knock into Render.
Try adding a check of IsPostBack before setting the loading your GridView. That will prevent you from overwriting it's values.
protected void Page_Load(object sender, EventArgs e) {
if(!IsPostBack) {
/*Populate your GridView*/
}
}
protected void GridView_RowUpdated(object sender, GridViewUpdatedEventArgs e)
{
/*show your calendar here if you need to*/
if(whatever) calendar.Visible = true;
}
This should work, if it doesn't then I'd recommend putting breakpoints in your Page_Load and RowUpdated methods and stepping through it, preferrably with a Watch on the gridview's datasource (it'll go red if it's changed) and a watch on calendar.Visible, to help you see if something has changed.
For the record, control events like OnRowUpdated will never fire before Page_Load unless explicitly called for some reason. Chances are you're just doing something where it's not updating the content of the GridView before it gets to the RowUpdated method, or it's overwriting the data in the GridView due to a lack of !IsPostBack check.

LinkButton (inside a Panel, but outside of UpdatePanel) OnClick event not causing parent page PostBack?

Using VS2005, ASP.Net 2.0, AjaxControlToolKit
I have a LinkButton in a Panel that contains an UpdatePanel with a GridView. The link button is outside the UpdatePanel. The OnClick event has this code:
protected void lnkOk_Click(object sender, EventArgs e)
{
foreach (GridViewRow row in grdProductSearch.Rows)
{
CheckBox chk = row.Cells[0].Controls[0] as CheckBox;
if (chk != null && chk.Checked)
{
// ...
}
}
Server.Transfer(Page.Request.RawUrl);
}
I need it to pass the selected values of the grid back to the Parent page in a post back. But all it does is close the Panel.
Any ideas why this is happening? or how can I achieve what I am trying to do?
Try putting everything inside the UpdatePanel. Sometimes this control messes up the page normal behavior.
I've seen several times that UpdatePanel control affect somehow (it's difficult to say where and how) the javascript of the page. For example, When you have the UpdatePanel declared as ChildrenAsTriggers="false" and declared AsyncPostBack triggers, if you have a Validation Summary inside, it never shows the validation errors done in the server.

How do I get dynamically added ASP.NET buttons to fire events?

This is probably a simple question but I am not an ASP.NET developer and I am quite stuck.
I have a simple search routine that returns between zero and several hundred results. Each of these must be added to the page as a button and I want to set the text of the button and the CommandArgument property so that when the button is clicked I can read the CommandArgument back and react accordingly.
However, when I click the button the event does not run at all. How can I get it to run?
The code for building the button list (simplified for readability) is as follows:
foreach (SearchResult sr in searchResults)
{
Button result = new Button();
result.Text = sr.name;
result.CommandArgument = sr.ID.ToString();
AccountSearchResults.Controls.Add(result);
result.Click += new EventHandler(SearchResultClicked);
AccountSearchResults.Controls.Add(new LiteralControl("<br/>"));
}
At the minute to test, I have popped a label on the form to put the CommandArgument in. This code is never executed though.
void SearchResultClicked(object sender, EventArgs e)
{
Label1.Text = ((Button)sender).CommandArgument;
}
You mentioned in another answer that you are adding these when a button is clicked. Looking at your code, I would suggest that you try setting a unique ID for each button added, then ensure that on loading the page that buttons with the same IDs and CommandArgument values are reloaded. When a dynamically loaded button is clicked, it must still exist on the page after postback for the event to fire.
I think the ID is all you need, plus your requirement for the CommandArgument). You could put the ID information in the ViewState if you can't get it repeat without a long search process.
Where are you adding this buttons?
if you are adding them inside another control then the event might be raising in the parent control. This happens on DataRepeaters and DataGrids for example.
I think you need to use the OnCommand event handler, rather than the OnClick i.e. try changing this:
result.Click += new EventHandler(SearchResultClicked);
to this:
result.Command += new EventHandler(SearchResultClicked);
UPDATE
Try changing the type of second argument to your event hander from EventArgs to CommandEventArgs. You might also have to set the CommandName property on your button i.e.
result.CommandName = "foo";

Resources