Using the code posted as answer at this question, it is possible to find the control that caused the postback action.
However, it is possible to check which event was called by this control? For example, identify an editing event fired by a GridView before the equivalent method (editing) be executed.
Thanks in advance.
It depends if the client code is providing this information. The standard GridView, for example, sets both __EVENTTARGET and __EVENTARGUMENT when a sort header link is clicked:
Request.Form["_EVENTTARGET"] contains "ctl00$MainContent$GridView1"
Request.Form["_EVENTARGUMENT"] contains "Sort$id"
where the __EVENTARGUMENT contains information that this is a Sort operation, and the column to be sorted on, separated by $.
For paging the __EVENTARGUMENT value looks similar:
Request.Form["__EVENTARGUMENT"] contains "Page$2"
Note though that not all controls populate __EVENTARGUMENT on postback, so you'll have to test.
Related
I am returning to ASP.NET after a long hiatus, and am sure I'm doing something simple wrong, but I can't seem to sort it out. I have a page with a few controls (a few Literals and one TextBox), the values of which I am populating from a database query in Page_Load. When the value of the TextBox is changed, it correctly does a postback and fires the TextBox_TextChanged method, but it also seems to re-execute Page_Load, so the new value entered by the user is overwritten with the original value from the database. The only way I seem to be able to find to prevent this is to wrap the line that sets the control value in an if (!this.IsPostBack), which works fine, but I'm curious if there is a more elegant way to do this.
Thank you in advance,
Steve
What do you mean, "When the value of the TextBox is changed, it correctly does a postback and fires the TextBox_TextChanged method?" What causes the postback?
Beware that the TextChanged method doesn't work like JS (or similar) -- no check is done on each keystroke. It actually only fires on a full postback and the text is then checked for changes.
Otherwise, you've answered your own question by checking for a postback.
I have a gridview with checkbox control as a template field and one bounded field..
The grid is binded on every postback through a function and the grid contents remain the same on every post back..now when i check one of the checkboxes and then click the button at the end of the page, I need to store that particular row information..but I'm not able to retreive that information because when I check and then click button..the page loads and then the grid again populates and then checkboxes become uncheck and no CheckedChanged event fires..Help me with this
I need to persist the state of checkbox on every postback even when it is checked..how to do this??
In the page_load event function, please use the following code for your persistent data
if (!IsPostBack)
{
//your static data
}
This particular problem is fairly common. I haven't seen any "simple" solution yet, but here are 3 separate methods I have used. Each was used because of a limitation in the system.
Solution 1
Use AJAX. By putting your controls within an update panel, you can persist the changes by making them "real-time" in the database. This is not really a "simple" solution, but in my opinion it is one of the easiest to implement. Since the change is psuedo-immediate, there is no real need to worry about post-backs and persistence.
Solution 2
Use a "change management" control of sorts. You can apply a hidden control whose value is used to keep track of any changes made in relevant controls. You would need to devise a coherent data structure that provide at least a control ID and the new value (possibly the old value if you need some kind of "roll-back" feature). This would need to be coded in JavaScript so that any changes to the hidden control's value were structured and not duplicated. Then on your postback you would need to read this control's value, make any pertinent changes, and then rebind your data as appropriate. This can be fairly cumbersome, and it would need to be well-documented in the event that you pass this application on to a successor.
Solution 3
Use the PostBack for CheckChanged events and keep all data managed in the view state. During the RowItemCreated event of the GridView you can find the checkbox control in the relevant cell and manually add the delegate handler to that control to handle the postback in the event of a CheckChanged event firing. You can then have the change immediate. The drawback to this is that PostBack events become frequent and heavy. If you're storing large amounts of data in the ViewState this also causes page load to be slow and unresponsive, so whatever structure you choose for the ViewState you'll want to keep it small.
This is possible if you are using asp.net 4.0 using
<asp:GridView id="GridView2" runat="server" EnablePersistedSelection="true">
</asp:GridView>
If you are using 3.5, you will have to retain checkbox info in viewstate. I hope this will be helpful.
http://www.codeproject.com/Articles/202938/How-to-select-multiple-records-from-the-GridView-a
Another Option:
This is how msdn have described a hotmail type gridview.. may be this can help.. this will require you to extend existing GridView Control.
http://msdn.microsoft.com/en-us/magazine/cc163612.aspx
Regards.
Alright so in the project I am working on I am making a hard coded asp:panel on the page and then filling it with:
A Drop Down list
An asp:Table, with an asp:TableHeaderRow
Add and Cancel Buttons
When the selectedIndexChanged event happens with the DropDownList the tablerow gets created then filled with 6 or so tablecells which then get asp:Textboxes placed inside of them.
Eventually they all get added to the tablerow which then gets added to the tablerowcollection.
That all works just fine,but when I go to add the information from these dynamically created TableRows with a foreach loop they are no where to be found but the TableHeaderRow is.
Also when I click add and let it go through the process I get no null exceptions and the only thing left after it is the header, all my rows disappear.
Anyways I feel that I am just missing something really dumb. I've looked through a lot of forums, posts, MSDN and never found an answer to my problem. Any help would greatly be appreciated!
You need to add your dynamic rows to your Table in Page_Init not Page_Load. If you are creating it in Page_Load your new rows won't be added to ViewState and you will see this problem.
Unfortunately you are adding them in response to a server side event which can get tricky. You still need to add the rows in Page_Init but when the page posts back and you at in Page_Init then the selectedIndexChanged event hasn't yet fired. It's too early in the page lifecycle.
If you want to know if it has fired at Page_Init the only way I have found is by examining Request.Form("__EVENTTARGET") collection at that point. This contains the control ID of the control that has triggered the postback - in your case this will be the dropdown list. The control that fired the event will be there but the ID will be qualified i.e not MyControID but ctl_MasterPageContentHolderID_NamingContainer1_MyControlID` or the like - so you will have to take it into account when looking for it. Once you have identified that that event has fired then you can add the rows. Once they are added there then they won't disappear.
As I say it is tricky to get working but I have done this successfully in the past. Generally dynamic controls can be very hard to work with for just this reason. You may want to consider alternatives. Best of luck with it anyway though.
I'm working on an asp.net website (using C#). I have implemented a detailsview as part of a data entry system for this website.
The detailsview contains a drop down list used to associate a category with the record being submitted to this data entry system.
The code behind file accesses a datasource (an SQL server 2005 database table), to determine the fields associated with a selected category and to generate checkbox controls based upon the fields available in that category
I understand (I think) the .net page lifecycle, and the necessity to add dynamic controls on each postback to maintain the controls and their "state". However:
I've read that I must add dynamic controls in the Page_Init/initialisation phase of the page lifecycle, in order for the dynamic controls properties and events to be available upon a postback
The value I require to query the datasource (and to determine the number and names of the dynamic controls for a category selection) is assigned in the dropdown list's SelectedIndexChanged event handler, which is always processed after the Page_init event
I'm not sure how I can pass the required value (the dropdown list's selected index) to the Page_Init event at the correct point in the page lifecycle (the Page_init event).
I would greatly appreciate any pointers/assistance from the stackoverflow community
and thank you for taking the time to read this post.
You do not have to add the controls in the init, you can add them in page_load just fine as well. It is often recomended to add them in the init as this is the point in the page lifecycle that controls defined in the markup are instantiated. Why do you need to assign the value to determine whether the controls should be added in the SelectedIndexChanged event. If it is based on the SelectedValue of a drop down list, can you not simply access the SelectedValue and assign the value on each post back, even if it has not changed. Then you could do it in the Page_Load and then add your controls afterwards.
The value you are after is posted back to the server and can be found in Request.Form NameValueCollection. The key is the name of the dropdown list.
On an ASP.NET page, I have a GridView populated with the results of a LINQ query. I'm setting the DataSource in code, then calling DataBind on it. In the GridView's RowDataBound event, I'm selectively hiding links in some GridView fields based on the query results. (For instance, I hide the "Show Parent" link of the row in question has no parent row.)
This works fine initially. But on postback (when I don't call DataBind, but the GridView stays populated through ViewState), the data displays, but the RowDataBound event (obviously) doesn't fire, and my links don't get hidden.
What's the best way to get the links to be hidden after a postback?
The RowDataBound event only fires when the GridView's data changes during the postback. The event is short-circuited for speed so it's not re-generating the exact same data unnecessarily. Use the RowCreated event to manipulate the HTML instead - it fires on every postback regardless of whether the data has changed.
Here's how I ended up solving this:
I created a serializable class with readonly properties: PK of a row, and a boolean for each link indicating whether it's enabled or not. We'll call it LinkVisibility.
I created a serializable class inheriting from KeyedCollection to hold instances of the class above.
I created a ViewState-backed property holding an instance of that collection.
In my Search procedure (populating the GridView), I clear the collection.
In RowDataBound, which initially shows/hides the links, I add a LinkVisibility instance to the collection for each row.
In Page.Load, when IsPostBack is true, I loop through the GridView rows. I look up the LinkVisibility for each one by PK in the collection (DataKeyNames is set in the GridView), and I set the links accordingly.
I don't know that this is the best way to do this, but it certainly does work, which is more than I can say for anything else I've tried.
1) You could have a Method - ProcessDataRows() that would get called once on grid_DataBound(...). And then when you need it after PostBack.
And that way you process all rows when you want.
2) You could have methods like ShowParentLink(). That are then bound to the LinkButton in the grid (if you're using an ItemTemplate) and the link would have
Visible='<%#ShowParentLink()%>'
I would have expected the viewstate to also reflect the fact that you have removed some of the links (assuming that they were removed before viewstate was saved).
Maybe thats the question you need to ask 'why do the removed links still appear in viewstate?'.
Another solution is to put the logic in the LINQ query, so that you end up with a boolean LINQ field like "ShowParentLink". Then you can just bind the Visible property of the HyperLink field to that value - no RowDataBound required.
protected void btnHazardRating_Click(object sender, EventArgs e)
{
gvPanelRole.RowDataBound += new GridViewRowEventHandler(gvPanelRole_RowDataBound);
gvPanelRole.DataSource = dtGo;
gvPanelRole.DataBind();
ModalPopup.Show();
}
void Process Rows()
{
... do something
... process complete
datagrid.DataBind();
}
A page cannot process postback events unless it is rebuilt exactly as it was before (the postback). If you re-hide your links during the page-init, then your click events and such should fire. Unfortunately, without seeing some sample code I can't get more specific.
Also the data RowDataBound does not fire because you are not data binding. You are rebuilding the page from the viewstate- "viewstate binding" for lack of a better word.