0
votes

Another day, another weird InfoPath problem...

So, I'm building custom ActiveX controls in C# by following these tutorials - mhttp://blogs.msdn.com/b/infopath/archive/2006/12/18/creating-complex-infopath-controls-in-c-sharp.aspx and http://blogs.msdn.com/b/infopath/archive/2005/04/15/creating-an-infopath-custom-control-using-c-and-net.aspx. Generally things are straightforward and I have working controls that can return simple values, xml, etc.

However, one thing asserted in the msdn posts is that InfoPath will repeatedly destroy and reinstantiate controls as the view is updated - and so you cannot store state in the control. I was surprised, then, to see that in InfoPath 2010, I absolutely can store state (fields, properties, .NET controls) in the control, and save it to xml when the form is submitted. Event stranger, putting a MessageBox.Show() in the control constructor indicates that the control is being repeatedly reinstantiated, but only one version is accessible to the user. I am somewhat troubled by this as I'm not sure why extra copies of the control are being instantiated, and this could cause a serious performance problem if the controls become complex

So, now I try it out in InfoPath 2007, and I find that the ActiveX control is indeed being destroyed and reinstantiated (destroying all state) every time the data changes. This basically means that all state will need to be stored somewhere (probably the form xml) to repopulate the control when it is refreshed.

This is obviously a pretty major difference between InfoPath 2007/2010 - but I can find no documentation, or any other mention, of the phenomenon. The articles cited above are pretty old and so correctly refer to the behavior of 2007. If anybody can shed any light on this I'd be very grateful!

1
I've found some documentation of this change: msdn.microsoft.com/en-us/library/… - it's pretty hidden away. So InfoPath 2007 controls implement the Microsoft.Office.Interop.InfoPath.InfoPathControl interface, while InfoPath 2010 controls implement InfoPathControl2. The latter has an extra method called RefreshState, which is called when the control is refreshed. The msdn doc for this method indicates:Tryptamine42
"In InfoPath 2007, when a change occurs to the XML node the control is bound to, InfoPath calls the SaveState() method implemented by the control so that InfoPath can destroy the control, and the control can successfully restore its state when it was reconstructed. In InfoPath 2010, changes were made so that ActiveX controls are not always destroyed and reconstructed when a change to the bound XML node occurs.Tryptamine42

1 Answers

0
votes

I've found some documentation of this change: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.infopath.infopathcontrol2.refreshstate%28v=office.14%29.aspx - it's pretty hidden away.

So InfoPath 2007 controls implement the Microsoft.Office.Interop.InfoPath.InfoPathControl interface, while InfoPath 2010 controls implement InfoPathControl2. The latter has an extra method called RefreshState, which is called when the control is refreshed. The msdn doc for this method indicates:

"In InfoPath 2007, when a change occurs to the XML node the control is bound to, InfoPath calls the SaveState() method implemented by the control so that InfoPath can destroy the control, and the control can successfully restore its state when it was reconstructed. In InfoPath 2010, changes were made so that ActiveX controls are not always destroyed and reconstructed when a change to the bound XML node occurs. To fully implement this change, InfoPath 2010 needs a way to communicate to the control that a change to the bound XML node has occurred, and that the control should refresh its state by reading the updated information in the XML node. To do that, the developer of the control must implement the RefreshState() method on the control."

So this is specified behaviour.

Some investigation with the Dispose() method shows that in InfoPath 2010, while new copies of the control are instantiated on every edit, they are immediately disposed, and so aren't hanging around taking up resources. While I'm not really sure why it's implemented this way, it clearly was intentional and so should be safe.