Row Editing in the grid doesn't work in first click - asp.net

I have a user control which contains a grid and three buttons for add,edit and delete.
I have placed this user control on an asp.net page.
I have OnClick events for these buttons.
When i click on add and delete buttons it's working fine but when i click on edit button,the onclick event of edit button is fired but the row in the grid doesn't appear in the edit mode, i have to click two times.
I don't know where is the problem.The onclick event handler for edit button is as follows:
protected void btnEditBankAccount_Click(object sender, EventArgs e)
{
grdBankAccounts.EditIndex = grdBankAccounts.SelectedIndex;
grdBankAccounts.RowSelectingEnabled = false;
}
Anyone please help.
my user control has a method which binds the grid to the data source, it's as follows
public void SetSupplierData(SupplierType Supplier)
{
if (Supplier != null)
{
ViewState["SupplierID"] = Supplier.SupplierId;
grdBankAccounts.DataSource = Supplier.BankAccounts;
grdBankAccounts.DataBind();
Session["BankAccounts"] = Supplier.BankAccounts;
}
}
the SetSupplierData method is called from the page where i have my user control.

In order to get this "in-place editing" in grids to work, I typically have to data-bind twice:
once in the OnInit or OnLoad method so that the button click event handlers have the data available to work on
in the OnPreRender method again to show the new values / new state (editing or not)
Marc

Related

two events fired simultaneously in ASP.NET

I have an update panel in my ASP.NET web form with a trigger that will fire a click event when the contents within my update panel is updated (it's a grid view with fields). The event that is fired when then take the changes user made and do some calculation and then update another update panel with that information. This is all fine and dandy when the user tabs along the form and fill out the form in a orderly fashion before hitting any buttons on the page.
If a user accidentally hits another button on the page while changing the content in my grid within the update panel, for example, the user enter a value in my grid view control, without tabbing, the user click the save button.
Logically, i believe that the trigger should fire the click event first (event A), and then the save button event (event B). But, consistently I haven't seen event A gets fire correctly while event B gets fire all the time ...
any thoughts on this?
is there a way to ensure event A always gets fired before event B?
also if event A update another update panel without the page will event B fire after the update is complete?
thanks.
You can try to block the form from post 2 times before gets update. Here is an example
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_initializeRequest(InitializeRequest);
prm.add_endRequest(EndRequest);
var fAlloToSubmit = true;
function AllowFormToRun()
{
if(!fAlloToSubmit)
alert("Please wait for the page to fully re-loaded.");
return fAlloToSubmit;
}
function InitializeRequest(sender, args) {
fAlloToSubmit = false;
}
function EndRequest(sender, args) {
fAlloToSubmit = true;
}
and on code behind add the onsubmit.
protected void Page_Load(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(Page.Form.Attributes["onsubmit"]))
{
Page.Form.Attributes["onsubmit"] = "return AllowFormToRun();";
}
}

ObjectDataSource - how can I bind only if button pressed

I have a button, which when presses populates a grid with data. If I add an ObjectDataSource, and bind the grid to it, it will populate the grid when the page loads. But I need to populate the grid only if the button is pressed, because it is a lengthy opperation. How should I accomplish this
add an event handler to ObjectDataSource's Selecting event like this:
protected void ObjectDataSource1_Selecting(object sender, ObjectDataSourceSelectingEventArgs e)
{
if (!IsPostBack)
{
e.Cancel = true;
}
}
and put a button on page, when it was clicked a postback will occur and ObjectDataSource will return data successfully.

Dynamic Event Handler lost after postback

I have a asp.net page with a button, the event the button needs to perform on it's click event needs to vary, dependant on what options are selected further up the page. The button itself is included in the master page, and it's actions are affected by selections made in the child page.
To do this, I have a method in the master page, that is called by the child page, when a users presses a button, that passes the Eventhandler to be used by that button, that is then assigned to masterpage eventhandler for that button:
public void assignEvent( EventHandler saveEvent)
{
this.SaveButtonEvent+= saveEvent
}
Then, when the save button on the master page, it calls that eventhandler
protected void save_Click(object sender, EventArgs e)
{
if (this.SaveButtonEvent != null)
{
this.SaveButtonEvent(this, e);
}
}
The event handler is assigned ok in the first section of code, however because pressing the save button causes a postback, the SaveButtonEvent event handler is set back to being null, and so nothing happens.
How can I preserve the contents of SaveButtonEvent Event Handler during postback, or is there a better way to be doing this?
EDIT:
I can get this to work by saving the EventHandler to the session, but this doesn't seem like a great idea.
When the user presses the button in the child page, store a value (in the viewstate) indicating what event handler should be passed. Then, in the load event of the child page, if it is a postback, always check the stored value and assign the event handler accordingly by calling the master page method.

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...

Modal popup on dropdown list selection

Is it possible to popup a modal(AJAX) on drop downlist selection.
I have a user control which has a ddl and another usercontrol which has that modal popup.On selection of specific item i need to popup modal.
Modal popup is in another usercontrol.
I did an example of how to do it entirely client side using a ClientEventPool - http://www.aaron-powell.com/blog/january-2009/fun-with-a-client-event-pool-and-modal-popups.aspx
For AJAX work avoid postbacks at all costs!
If I am reading you correctly, you will need to use either chained events or event bubbling to force the drop down selection to fire an event. Then your second user control must listen for that event, and fire the event that "shows" the modal popup.
Without testing code, your structure on the primary control might look like this:
public delegate void DDLHandler(int selectedValue);
public event DDLHandler DDLChanged;
public void DDLChanged(int selection)
{
if (DDLChanged != null)
{
DDLChanged(selection);
}
}
Then you drop down control has it's event wired to call the handler
protected void ddlOne_SelectedIndexChanged(object sender, EventArgs e)
{
//fire event handler for fetching value for this selection
DDLChanged(Int32.Parse(ddlMeasurementOptions.SelectedValue));
}

Resources