By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
455,467 Members | 1,448 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 455,467 IT Pros & Developers. It's quick & easy.

Property assignment causes strange designer-generated code

P: n/a
Yesterday Visual Studio gave me a strange error both at compiletime and at
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 'CleanCodeControls.Support.ConnectionDetails' was not found. File:
MainForm.resx

Error 2 SerializationException: 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 'CleanCodeControls.Support.ConnectionDetails' 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
'CleanCodeControls.Support.ConnectionDetails' was not found. Line 169,
position 5.
###########################

The visual designer manifests essentially the same error:
###########################
The constructor to deserialize an object of type
'CleanCodeControls.Support.ConnectionDetails' was not found.
###########################

These errors appeared because of this designer-generated statement in
MainForm.Designer.cs...
###########################
new
CleanCodeControls.Support.ConnectionDetailsCollect ion().Add(((CleanCodeControls.Support.ConnectionDe tails)(resources.GetObject("leftSqlEditor.Configur ationList"))));
###########################

That line was embedded in a set of statements initializing a custom control
inside InitializeComponent; here's some context. Instead of assigning to the
ConfigurationList property it created this unusual line.
###########################
this.leftSqlEditor.AutoExecuteMode = false;
this.leftSqlEditor.AutoHighlightMode = false;
this.leftSqlEditor.CommandTimeout = 60;
new
CleanCodeControls.Support.ConnectionDetailsCollect ion().Add(((CleanCodeControls.Support.ConnectionDe tails)(resources.GetObject("leftSqlEditor.Configur ationList"))));
this.leftSqlEditor.ContainerTest = false;
this.leftSqlEditor.CsvPath = ".";
this.leftSqlEditor.DbConfigurationName = "--";
this.leftSqlEditor.DiagLabel = "LeftSqlEditor";
this.leftSqlEditor.Dock = System.Windows.Forms.DockStyle.Fill;
this.leftSqlEditor.LocalMode = false;
###########################

Corresponding to this was a section in the MainForm.resx file:
###########################
<data name="leftSqlEditor.ConfigurationList"
mimetype="application/x-microsoft.net.object.binary.base64">
<value>--- encoded binary data here --- </value>
</data>
###########################

By deleting the line in MainForm.Designer.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 ConnectionDetails. I traced it to the line indicated with arrows
below (the ConfigurationList assignment inside this ContainerTest property)
of my SqlEditor custom control. leftSqlEditor is an instance of SqlEditor.
Removing the assignment to the ConfigurationList 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.ContainerTest = containerTest;

// provide a default connection to get bound data as well
>>>> ConfigurationList = new ConnectionDetailsCollection {
new ConnectionDetails
{
ConfigName = "sqlExpress",
ConnectionString =
@"Data Source=.\SQLEXPRESS;Initial
Catalog=AdventureWorks;"+
@"Integrated Security=True;Persist Security
Info=True",
DbType = ConnectionStringManager.DBTypes.SqlServer
}
};

DbConfigurationName = "sqlExpress";
}
}
private bool containerTest = false;

public ConnectionDetailsCollection ConfigurationList
{
get { return configurationList; }
set
{
configurationList = value;
UpdateForChangedConfigList();
}
}
private static ConnectionDetailsCollection configurationList;

###########################
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 CleanCodeControls.Support
{
public class ConnectionDetailsCollection : Collection<ConnectionDetails>
{
// empty
}
[Serializable]
public class ConnectionDetails : ICloneable, ISerializable
{

public ConnectionDetails(string configName) { this.configName =
configName; }

public ConnectionDetails() { }

public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("ConfigName", configName);
info.AddValue("ConnectionString", connectionString);
info.AddValue("DbType", dbType);
info.AddValue("RememberPassword", rememberPassword);
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?
Jul 2 '08 #1
Share this Question
Share on Google+
6 Replies


P: n/a
Thanks for the information, but it did not fix the issue.

Adding the first item:
[DesignerSerializationVisibility(DesignerSerializat ionVisibility.Content)]

changed the generated code from:
new
CleanCodeControls.Support.ConnectionDetailsCollect ion().Add(((CleanCodeControls.Support.ConnectionDe tails)(resources.GetObject("leftSqlEditor.Configur ationList"))));
to:

this.leftSqlEditor.ConfigurationList.Add(((CleanCo deControls.Support.ConnectionDetails)(resources.Ge tObject("leftSqlEditor.ConfigurationList"))));

Next, I added this serialization constructor (with a couple modifications to
your code to get it to compile):

protected ConnectionDetails(SerializationInfo info, StreamingContext
context)
{
configName = info.GetString("ConfigName");
connectionString = info.GetString("ConnectionString");
dbType = (ConnectionStringManager.DBTypes)Enum.Parse(
typeof(ConnectionStringManager.DBTypes),
info.GetString("DbType"));
rememberPassword = info.GetBoolean("RememberPassword");
description = info.GetString("Description");
}

And finally I added the SetType at the top of GetObjectData.

Now attempting to open the form in the designer yields this error:

"Method 'CleanCodeControls.Support.ConnectionDetailsCollec tion.Add' not
found. "

My ConnectionDetailsCollection class, as a reminder is just this empty class
definition:

public class ConnectionDetailsCollection : Collection<ConnectionDetails>
{
// empty
}

So are we getting closer to a solution? My understanding of the connections
for serialization is weak.
Jul 7 '08 #2

P: n/a
Hi Michael,

Thank you for your reply!
Next, I added this serialization constructor (with a couple modifications
to your code to get it to compile):

I didn't know the type of the DbType property and I assumed it as the type
of String. Thank you for showing us how you correct this line of code!
Now attempting to open the form in the designer yields this error:
"Method 'CleanCodeControls.Support.ConnectionDetailsCollec tion.Add' not
found. "

Please delete the custom control from the Form and delete the item
"leftSqlEditor.ConfigurationList" from the form.resx file first. Re-build
the project and re-open the form in the designer and add the custom control
onto the form to see if the problem still exists.

Sincerely,
Linda Liu
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
ms****@microsoft.com.

This posting is provided "AS IS" with no warranties, and confers no rights.

Jul 8 '08 #3

P: n/a
Rebuilding as you indicated seems to have cleared up the issue.
As a final question on this topic, could you point me to the MSDN pages that
describe these pieces necessary for proper serialization?

I looked through "Introducing XML Serialization"
(http://msdn.microsoft.com/en-us/libr...hh(VS.80).aspx)
but I cannot find where it talks about any of the three points you itemized
to fix my problem.

Thanks!
Jul 10 '08 #4

P: n/a
Hi Michael,

Thank you for your reply!

As for the first point, properties that do not have a
DesignerSerializationVisibilityAttribute will be treated as though they
have a DesignerSerializationVisibilityAttribute with a value of Visible.
For a property of type collection, a private variable of type collection
will be created and initialized with the items configured at design time
first and then assigned to the public collection property within the
InitializeComponent method.

In your scenario, you configure the ConfigurationList property within the
set accessor of the ContainerTest property, so the form designer doesn't
know which property the private variable should be assigned to. At this
time, we can specify a DesignerSerializationVisibilityAttribute with a
value of Content to address the problem.

The following MSDN document may help:
'How to: Serialize Collections of Standard Types with the
DesignerSerializationVisibilityAttribute'
http://msdn.microsoft.com/en-us/library/ms171833.aspx

As for the second point, you implement the ISerializable interface for the
ConnectionDetails class, so the value of this property will be serialize
and stored in the form's resx file. When the form is re-opened, a design
time error occurs. So it's obvious that something is wrong when the form
designer is trying to construct instances of the
ConnectionDetailsCollection class.

There's a comment "The ISerializable interface implies a constructor with
the signature constructor (SerializationInfo information, StreamingContext
context). " in the following MSDN document that explains this exactly:
http://msdn.microsoft.com/en-us/libr...zation.iserial
izable.aspx

As for the third point, after I configured the ConfigurationList property
in the designer and compile the project, I found that the value under the
Type column of the item "leftSqlEditor.ConfigurationList" within the
form.resx is null. So the type of the resource item is missing.

The sample in the
"http://msdn.microsoft.com/en-us/library/system.runtime.serialization.iseria
lizable.aspx" shows that we should call the SerializationInfo.SetType
method to set the Type of the object to serialize in the
ISerializable.GetObjectData implementation.

Hope this helps.
If you have any question, please feel free to let me know.

Sincerely,
Linda Liu
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
ms****@microsoft.com.

This posting is provided "AS IS" with no warranties, and confers no rights.

Jul 11 '08 #5

P: n/a
Thank you, Linda. The information you provided has been very enlightening!
Jul 11 '08 #6

P: n/a
You're welcome, Michael!

If you have any other questions in the future, please don't hesitate to
contact us. It's always our pleasure to be of assistance.

Have a nice day!

Sincerely,
Linda Liu
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
ms****@microsoft.com.

This posting is provided "AS IS" with no warranties, and confers no rights.

Jul 14 '08 #7

This discussion thread is closed

Replies have been disabled for this discussion.