Introduction
This tip shows how to solve an exception you may receive when running an application that uses a SplitContainer
built against different versions of the .NET Framework. It also explains why the exception happens.
Background
After modifying a dialog to use a SplitContainer
instead of a Splitter
, I received the following exception when the application was built and run with Visual Studio 2005.
System.InvalidCastException: Unable to cast object of type 'System.Windows.Forms.SplitContainer' to type 'System.ComponentModel.ISupportInitialize'.
A quick internet search revealed others that had encountered the same exception. Most of them had to do with targeting Framework 4.0 initially and then switching to an earlier version. The fix that was mentioned removes two lines from the generated code in the *.Designer.cs file. But I wanted to know why the lines were generated, what the generated code differences are for different .NET Frameworks and whether the fix is really a good solution.
I started by creating a simple project and targeting different Frameworks so I could see the generated code and its differences. The Visual Studio 2010 form designer, targeting Framework version 4.0, generates the code below (shown in C#) when there are objects contained by a SplitContainer
.
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
.
.
.
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
When targeting earlier versions of the Framework, these two lines are not generated. So why does this code cause problems? The problem is that the SplitContainer
class doesn't inherit from ISupportInitialize
until Framework version 4.0. Because of this, ealier Frameworks can't cast a SplitContainer
object to an ISupportInitialize
object! After the code is generated for Framework 4.0, changing the targeted Framework version won't regenerate code unless a change is made in the form designer.
There was my problem! The SplitContainer
was added to my project via Visual Studio 2010 with Framework 4.0 as the target. The exception I saw occurred in Visual Studio 2005 which targets Framework 2.0. I know, I was asking for it by modifying Framework 2.0 code with Visual Studio 2010 targeting Framework 4.0, but we won't get into the reasons for that!
Using the code
I should change the heading above to read "Not using the code." The solution to the problem is simply to remove the SplitContainer
BeginInit and EndInit calls as mentioned at the websites I found. However, this raises a question. Since Visual Studio generates the calls for Framework 4.0, if they are removed, will it create a problem when the target is Framework 4.0? If there is a problem, SplitContainer
isn't a good candidate for code that needs to target different Framework versions.
To find the answer, lets take a look at the ISupportInitialize
MSDN documentation. Under the Remarks section is the following quote.
ISupportInitialize
allows controls to optimize multiple property assignments. As a result, you can initialize co-dependent properties or batch set multiple properties at design time.
Call the BeginInit method to signal the object that initialization is starting. Call the EndInit method to signal that initialization is complete.
This indicates that the BeginInit/EndInit calls are an optimization and it should be OK to remove them. So, SplitContainer
can be used safely in code that targets various versions of the .NET Framework (including 4.0).
Points of Interest
A form of this problem did show up in pre-release versions of Visual Studio 2010. The BeginInit and EndInit calls were generated by the form designer even when the target Framework was less than 4.0. This is mentioned in the Microsoft Connect link below.
http://connect.microsoft.com/VisualStudio/feedback/details/531011/winforms-designer-generates-invalid-cast-with-isupportinitialize-interface
History
- March 28, 2012 - Version 1.0.