designtime that had no obvious connection to anything I had changed recently.
After some effort tracking down the problem I discovered first a workaround,
then the real cause of the problem. I would like to understand why what I am
doing is frowned upon by Visual Studio and how to do this properly.
My application is in one solution; supporting libraries including custom
controls in another. I am using C# in VS2008 and compiling to .NET 2.0 on
WinXP.
These are the compiletime errors:
############### ############
Error 1 Invalid Resx file. Type could not be read from the data in line
169, position 5. The type's internal structure may have changed. Either
implement ISerializable on the type or provide a type converter that can
provide a more reliable conversion format, such as text or an array of bytes.
The conversion exception was: The constructor to deserialize an object of
type 'CleanCodeContr ols.Support.Con nectionDetails' was not found. File:
MainForm.resx
Error 2 SerializationEx ception: Type could not be read from the data in
line 169, position 5. The type's internal structure may have changed.
Either implement ISerializable on the type or provide a type converter that
can provide a more reliable conversion format, such as text or an array of
bytes. The conversion exception was: The constructor to deserialize an
object of type 'CleanCodeContr ols.Support.Con nectionDetails' was not found.
XmlException: Type could not be read from the data in line 169, position 5.
The type's internal structure may have changed. Either implement
ISerializable on the type or provide a type converter that can provide a more
reliable conversion format, such as text or an array of bytes. The
conversion exception was: The constructor to deserialize an object of type
'CleanCodeContr ols.Support.Con nectionDetails' was not found. Line 169,
position 5.
############### ############
The visual designer manifests essentially the same error:
############### ############
The constructor to deserialize an object of type
'CleanCodeContr ols.Support.Con nectionDetails' was not found.
############### ############
These errors appeared because of this designer-generated statement in
MainForm.Design er.cs...
############### ############
new
CleanCodeContro ls.Support.Conn ectionDetailsCo llection().Add( ((CleanCodeCont rols.Support.Co nnectionDetails )(resources.Get Object("leftSql Editor.Configur ationList"))));
############### ############
That line was embedded in a set of statements initializing a custom control
inside InitializeCompo nent; here's some context. Instead of assigning to the
ConfigurationLi st property it created this unusual line.
############### ############
this.leftSqlEdi tor.AutoExecute Mode = false;
this.leftSqlEdi tor.AutoHighlig htMode = false;
this.leftSqlEdi tor.CommandTime out = 60;
new
CleanCodeContro ls.Support.Conn ectionDetailsCo llection().Add( ((CleanCodeCont rols.Support.Co nnectionDetails )(resources.Get Object("leftSql Editor.Configur ationList"))));
this.leftSqlEdi tor.ContainerTe st = false;
this.leftSqlEdi tor.CsvPath = ".";
this.leftSqlEdi tor.DbConfigura tionName = "--";
this.leftSqlEdi tor.DiagLabel = "LeftSqlEditor" ;
this.leftSqlEdi tor.Dock = System.Windows. Forms.DockStyle .Fill;
this.leftSqlEdi tor.LocalMode = false;
############### ############
Corresponding to this was a section in the MainForm.resx file:
############### ############
<data name="leftSqlEd itor.Configurat ionList"
mimetype="appli cation/x-microsoft.net.o bject.binary.ba se64">
<value>--- encoded binary data here --- </value>
</data>
############### ############
By deleting the line in MainForm.Design er.cs and deleting the <dataelement
in the MainForm.resx file, I could then compile successful and open the form
in visual designer. However, everytime I re-display the form in the visual
designer those code chunks are inserted again.
I digged deeper to determine why those lines were being generated all of a
sudden, because I had not changed anything related to the serialization or
structure of ConnectionDetai ls. I traced it to the line indicated with arrows
below (the ConfigurationLi st assignment inside this ContainerTest property)
of my SqlEditor custom control. leftSqlEditor is an instance of SqlEditor.
Removing the assignment to the ConfigurationLi st property removes the
generation of the above offending code by the visual designer.
############### ############
public bool ContainerTest
{
get { return containerTest; }
set
{
containerTest = value;
// signal to fill unbound DataGridView
dataGridView.Co ntainerTest = containerTest;
// provide a default connection to get bound data as well
new ConnectionDetai ls>>>> ConfigurationLi st = new ConnectionDetai lsCollection {
{
ConfigName = "sqlExpress ",
ConnectionStrin g =
@"Data Source=.\SQLEXP RESS;Initial
Catalog=Adventu reWorks;"+
@"Integrated Security=True;P ersist Security
Info=True",
DbType = ConnectionStrin gManager.DBType s.SqlServer
}
};
DbConfiguration Name = "sqlExpress ";
}
}
private bool containerTest = false;
public ConnectionDetai lsCollection ConfigurationLi st
{
get { return configurationLi st; }
set
{
configurationLi st = value;
UpdateForChange dConfigList();
}
}
private static ConnectionDetai lsCollection configurationLi st;
############### ############
Here are the relevant code highlights of the object that is apparently
having serialization problems, though this code has been working fine even
with the Properties/Settings page for over 6 months. I can, for instance, go
to the Properties/Settings page of the application, click on the ellipsis for
this setting, and VS invokes a collection editor to allow manipulation of the
collection without complaint. My understanding was that this uses the
serialization in question.
############### ############
namespace CleanCodeContro ls.Support
{
public class ConnectionDetai lsCollection : Collection<Conn ectionDetails>
{
// empty
}
[Serializable]
public class ConnectionDetai ls : ICloneable, ISerializable
{
public ConnectionDetai ls(string configName) { this.configName =
configName; }
public ConnectionDetai ls() { }
public void GetObjectData(S erializationInf o info, StreamingContex t context)
{
info.AddValue(" ConfigName", configName);
info.AddValue(" ConnectionStrin g", connectionStrin g);
info.AddValue(" DbType", dbType);
info.AddValue(" RememberPasswor d", rememberPasswor d);
info.AddValue(" Description", description);
}
}
}
############### ############
So why does my particular sequence of code generate these misbehaving lines
of code, and why are they misbehaving? Or to cut to the chase: what could I
do to fix this?