dynamic construction of checkboxes in a asp:table problem with events - c#

I'm currently dynamically building an asp:table which contains checkboxes
these checkboxes have a CheckChanged event as an auto postback.
v_articleCheckBox.CheckedChanged += new EventHandler(v_articleCheckBox_CheckedChanged);
I am storing the checkbox states in the viewstate and I am rebuilding the table every page load so that the viewstate may then be re applied to the check boxes.
For every checkbox but the first this works perfectly.
The odd case is that the first checkbox works on the check event but simply does not call the v_articleCheckBox_CheckedChanged method on the uncheck event
Does anyone have an idea?
I was thinking of adding a dummy checkbox as a first entry in the table and then simply hide it from the client. but this seems to be a bad workaround.

I'm curious: what was the issue? –
splattne (Nov 27 at 11:39)
I am curious too – JohnIdol (Nov 27 at
13:48)
I resolved the issue by modifying my logic so that some events were fired on a more generic basis and I simply avoided the issue.
I have no idea about the why or how this was occurring; I simply found a work around that suited my needs.

Related

Enable/disable TextBox on FormView.ModeChanged

I have DropDownList and a TextBox in the EditTemplate of my FormView. All I want is to enable/disable the TextBox based on whether the first entry of my DropDownList is selected:
When the FormView is switched to Edit mode by the user
When user changes the selected item of the DropDownList during Edit mode.
I have achieved the second one through JS and that's working fine, but the first one is proving too difficult. I've tried to do this in ModeChanged event of the FormView, but for some reason the following call returns null in the event:
MyFormView.FindControl("MyDropDownListID");
What am I missing here?
(I'm making sure that MyFormView.CurrentMode is FormViewMode.Edit before making the above call)
One of those times when you pull your hair for hours with a problem, then post it on SO and find the solution in the next few minutes. Anyone else trapped into this, the problem is that the controls of a databound FormView aren't created yet at the time of ModeChanged or Page_Load. You must call the above line in DataBound event and it will work fine.

"Control with id could not be located or a different control is assigned to the same ID after postback." Error

I have a web-application in .NET framework 4.5 with code behind C#.
I am using a RadGrid of telerik Asp.Net Ajax control. I am creating it dynamically from code behind in PageInit event and adding it to a div that is statically defined in aspx file.
Now, for each row I am having a button that is used to expand and collapse the row using JQuery script.
I also have a RadCalendar on the page and I am fetching records according to selected date range.
Now, the problem is, if I select a date range from 1st to 16 days, it works fine. If I select 1st to 30 days then also there is no problem. But now if I select 1st to 8, it gives me the error show below :
Server Error in '/' Application.
An error has occurred because a control with id 'ctl00$ContentPlaceHolder1$gvGridViewDemo$ctl00$ctl09$Detail20$ctl06$Detail10$ctl04$ctl10' could not be located or a different control is assigned to the same ID after postback. If the ID is not assigned, explicitly set the ID property of controls that raise postback events to avoid this error.
I am NOT using any ajax in this page, so on date selection it gets full postback. Also I had set viewstate to false, ViewstateMode to disable and ClientId = autoId for both - Button and Gridview. But I am not able to get rid of this.
Can anyone help me to get rid of this ridicules error?
P.S. I have checked the link An error has occurred because a control with id {0} could not be located or a different control is assigned to the same ID after postback and according to the comment I am having string.format() in my code. But I have commented it and still I am facing the same issue.
Resolved it by myself. I do not consider it to be the great solution I have discovered but I am answering this question that it might help someone who wants to get rid of this kind of issue and tired of finding the exact solution.
I have solved it by debugging skills with Trial and Error methodology (it requires so much patience in oneself).
What I did is, I started commenting some of the code that places dynamic controls on the page and checked for result whether the same error is generated or not? If yes, then you are commenting wrong code. So just remove the comments, make that portion as it was and move on.
At last I found that there were some dynamically generated tool-tips; I was used to display some additional details on every cell of the grid view (RadGrid), were creating this error. On PageInit I was clearing all of the controls of the division and adding a grid view by code behind. So each time the request gets initiated, it clears all of the controls and adds them newly.
However, the objects of tool-tip (I have used RadTooltip to display the tool-tip on cell) were not getting cleared from the page across the postbacks.
So I just applied a new ID to each tool-tip using its cell's (cell of grid) client id + DateTime.Now.Ticks.ToString(), and I kicked off myself from this weird error.
I see you solved it, yet this may be useful in the future if you have problems with RadTooltip, I had a couple of issues resolved with this: http://www.telerik.com/help/aspnet-ajax/tooltip-troubleshooting-common-issues.html.
I was getting this problem too. What fixed it was explicitly adding ID values to all the Control objects I was dynamically loading onto my screen.
It happens for me when I have multiple command field in my grid view. I converted them to template fields and everything worked fine!

Checkbox control in gridview

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.

How to get the information from a dynamically created TableRow C#/Asp.Net?

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.

GridView RowDataBound doesn't fire on postback

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.

Categories

Resources