ProgrammingFilter ( Help me before I jump out this window!
May 22, 2008 8:39 AM   Subscribe

Help figure out what my options are for solving this programming dilemma. I've inherited an project (C#) that is poorly written and even more poorly documented. Apparently the previous owners made a change that broke a page and I am stumped as to how to fix it. It has to do with events not firing for dynamically loaded user controls. If you're still interested, read on. If not, I don't blame you.

Okay, here's the nitty-gritty. I have a report page (we'll call it Report_1) that dynamically loads one of a few user controls depending on the criteria specified. This is happening late in the page life cycle (i.e. well after Page_Load()). For the purpose of this question we'll just focus on one user control (even though the problem is with all of them).

The user control contains a DataGrid and a handful of column templates. Each column template contains a LinkButton control with an OnCommand attribute. The idea is that when the LinkButton is clicked the user is redirected to another more specific report (we'll call this Report_2). So when the LinkButton is clicked the specified event handler should be called, the criteria assembled in a particular format for Report_2 and stored in session, and the user redirected to the Report_2 page which grabs the criteria and runs the report. If you're still with me you may already know the problem. Dynamically loading user controls after Page_Load() causes any events in the control not to fire (see HERE and HERE).

I need some way to get to a method within the user control code behind when one of the LinkButtons is clicked and that's where it gets complicated. I'll list the options that I can see and why they don't seem to work.

1. Explicitly add ID to LinkButton controls. This is the recommended fix I see the most, and it makes sense if you're explicitly creating the controls, but how do you do this when you're dealing with controls in a template? There could be 1-n controls created depending on the data. I tried grabbing the control using the ID specified in the template and then programmatically assigning an ID in ItemDataBound and ItemCreated, but it didn't seem to have any effect.

2. Recreate the controls in the Page_Load() event. The first link above contains a link to an example of how to do this. Again, the problem is that I'm dealing with a template so I don't have the ability to recreate each of the LinkButtons (that I know of). I don't even think this makes sense in my situation.

3. Force postback by populating OnClientClick with ClientScript.GetPostBackEventReference(). I can use this to pass the info I need but I have to capture it in the Page_Load() event of the hosting page (Report_1) which is really ugly for a number of reasons. The Page_Load() event in the user control apparently doesn't get called during postback. At least not when postback is done this way. Another problem is that the functionality used to build the criteria for Report_2 is contained in a class that is inherited by the user control, not the hosting Report_1 page, so I cannot properly assemble the criteria in the format expected by Report_2 in Report_1's code behind. It has to be done in the user control code behind.

So the dilemma is that I can postback to the hosting page (Report_1) and not get to Report_2 or I can get to Report_2 from the user control but I can't get to an event handler in the user control... if that makes any sense. I'll be happy to clarify anything that needs clarifying.

My brain is in a bit of a fog and I'm hoping I'm missing an elegant and simple solution. If anyone can help me with this I will be forever in your debt!
posted by jluce50 to Computers & Internet (6 answers total)
One other thing I thought of is replacing the LinkButtons in the template with PlaceHolders and creating the LinkButtons (and explicitly setting the ID) in ItemCreated or ItemDataBound event handlers. The problem with this is I can't figure out how to bind the data to the LinkButton at this point.
posted by jluce50 at 9:07 AM on May 22, 2008

It's hardly the most elegant solution in the world, but one thing I've done is:

1. Set up a hidden control on the page. (If you're in 1.1 this will be a hidden input with runat=server, if you're using 2.0 it will be a HiddenField). Default its value to 0.

2. Write a Javascript function that inputs a value, writes it to your hidden control, and submits the form. Put this Javascript in your linkbutton's OnClick attribute, passing in the grid key ID.

3. In the Page_Load function, check your hidden control's value. If it is non-zero do your necessary processing and set it to zero.

It's not beautiful, but it should do what you need it to do.
posted by graymouser at 10:31 AM on May 22, 2008

The main problem with that is that I'd have to check the value and do the processing in the Page_Load() of the hosting page rather than in the Page_Load() of the user control. I'm hesitant to to that because the hosting page has multiple user controls that I would have to do this for and it makes the page and the controls more tightly bound than I would like. Having said that, it's looking more and more like this is the only solution available.
posted by jluce50 at 11:43 AM on May 22, 2008

Hmm. I hadn't thought about the user control aspects of this. What about trying to load the controls in the Page_Init event instead of Page_Load? Will that allow the events you need to fire? I'm not sure off hand, but it might be worth a try.
posted by graymouser at 12:58 PM on May 22, 2008

Not really. The user specifies the report type and clicks the Submit button which fires an event handler that loads the custom control based on the report type specified. Loading the the control in the OnInit() isn't an option when you need user input to know which control to load.
posted by jluce50 at 2:45 PM on May 22, 2008

To sort of cut the gordian knot, would it be a terrible problem to have the LinkButton call some Javascript function that redirects to a page where you see Report2 with any parameters passed in the query string? I know it seems like a problem when you should be able to handle this in the CodeBehind, but from what I'm seeing it may just work.
posted by graymouser at 4:07 PM on May 22, 2008

« Older Vitamin C Shower Filters--Do they work?   |   From C++ to Java Newer »
This thread is closed to new comments.