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.
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
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.
- March 28, 2012 - Version 1.0.