PDA

View Full Version : User control in a repeater itemtemplate


CheekyTinker
07-10-2005, 08:06 AM
Hi

I have a web usercontrol which is placed inside the itemtemplate of a repeater. When the on load event fires for the control the control attempts to access a property which should have been initialised by the application context, but hasn't. The property is initialised correctly when the control is placed on a page outside of a repeater.

As a work around I've put a check to see if the property is null, if so I access the ApplicationContext directly from the control to retrieve a reference to the object and initiliase the property manually. Obviously this is not the way forward, what am I doing wrong?

Control config entry:


<object name="HardBopRecords.WebApp.Controls.ImageViewer" type="HardBopRecords.WebApp.Controls.ImageViewer, HardBopRecords.WebApp" singleton="false" lazy-init="false">
<property name="ImageProcessingService">
<ref object="ImageProcessingService" />
</property>
</object>


Referenced object config entry:



<services xmlns="http://www.springframework.net" default-lazy-init="true">
<object name="ImageProcessingService" type="HardBopRecords.Services.Image.ImageProcessingServi ce, HardBopRecords.Services">
</object>


Reference to control in repeater:


<ItemTemplate>
<TR>
<TD class="ListTableItem"><HARDBOPRECORDS:IMAGEVIEWER Src='<%#DataBinder.Eval(Container, "DataItem.Image.FileName")%>' ProcessedSrc="<fileName>_table.jpg" Alt='<%#DataBinder.Eval(Container, "DataItem.Image.Name")%>' id="Imageviewer1" ActionName="table" ImageFormat="jpg" runat="server"></HARDBOPRECORDS:IMAGEVIEWER></TD>



Thanks

Aleks Seovic
08-07-2005, 06:26 PM
It seems like you are not doing anything wrong...

I haven't had much time to investigate, but it looks like the problem is consequence of the dynamic control creation -- repeater control creates child items based on template *after* all dependency injection code for the page and its contained controls has executed, which means that controls created by the repeater won't have dependencies injected properly :-(

Solution would be to change DI mechanism for the controls from "push' to "pull", but that opens another can of worms. I'll log this in JIRA and work on it as soon as I have some more time.

Regards,

Aleks

spmva
09-09-2005, 08:08 PM
is this:
problem is consequence of the dynamic control creation
the same reason why the dynamic loading of a control through the LoadControl(path) method does not load the control with injected dependies?

thanks,

steve

Aleks Seovic
09-09-2005, 09:29 PM
Yup, same thing... :(

spmva
09-09-2005, 10:54 PM
I suppose that if there were any workarounds you would have said so. Just in case, however, i'll ask anyway.

Any workarounds for the LoadControl(path) issue? How about some of that "aleks magic"? [smile]

Assuming no workarounds or magic, I'm going to have to figure something out. Hopefully it won't be too awful.

Thanks for your help as usual.

Steve

Aleks Seovic
09-10-2005, 02:15 AM
Actually, there is no need for magic in the case of LoadControl method, even with the current implementation.

There are several options:

1. Load all the controls in OnInit method, before OnLoad is called. Page.OnLoad calls InjectDependenciesRecursive, passing itself as a parameter, so all the controls that belong to the control hierarchy of the page at this point will have their dependencies injected.

2. Call InjectDependenciesRecursive directly, passing dynamically loaded control as a parameter -- that's exactly what I used to do in AbstractWizard implementation in order to inject dependencies into dynamically loaded wizard steps.

3. Get the latest code from CVS, where LoadControl method is overriden in the Page class to inject dependencies into dynamically loaded controls :)

Later,

Aleks

P.S. Repeater problem still remains though, I still have to look into it.

spmva
09-10-2005, 02:53 AM
I just ran a CVS update and didn't pick up any changes to the Page.cs file. My version doesn't have that overriden LoadControl method, so I guess there's a problem somewhere. I noticed SourceForge's web site is under maintenance...perhaps that has something to do with it. I'll try again later...or better yet tomorrow...it's getting late.

Option 3 is good for me. Thanks for the quick response.

Best regards,

Steve

spmva
09-10-2005, 11:33 AM
Got it! The controls are loading nicely. Thanks again.

Best regards,

Steve

Mark Pollack
09-11-2005, 03:23 PM
Hi Steve,

Glad it is working. FYI, there is a time lag between developer cvs access and anonymous cvs access. It can be up to 24hrs (AFAIK) so that is "normal" behavior believe it or not.

Cheers,
Mark

Erich Eichinger
08-30-2006, 08:22 AM
As Aleks stated above:

The solution is to do all LoadControl() and DataBind() calls during OnInit() of your controls & pages. In this case Dependencies will get injected into all your controls - even the ones inside a Repeater.

If - for some reason - you are not able to call DataBind() during OnInit(), you may inject dependies at any time using a call to


Spring.Util.WebUtils.InjectDependenciesRecursive(I ApplicationContext applicationContext, Control control)


Calling LoadControl() and DataBind() during OnInit() will also resolve an issue with the DataBindingManager and dynamically loaded server-side controls (TextBox etc.): Unbinding Data is done during OnLoad(). If a control gets loaded dynamically during OnLoad(), the HttpRuntime will populate PostData *after* OnLoad() has finished. Thus at the time data is unbound into the controller, not all values will be available at this stage.

cheers,
Erich