Solved

Code generation for property failed : Type ... is not marked as serializable

Posted on 2015-02-01
9
691 Views
Last Modified: 2015-03-08
I'm designing a custom control.  It has several properties and one of them is a List<ColumnItem>.  ColumnItem is a class that i've made.  This list is using an CollectionEditor.  I change some stuff, compile and weird thing happen.  So i try to debug it, i check at the form containing my custom control and i get this error: "Code generation for property 'ColumnItems' failed.  Error was: 'Type 'System.Windows.Forms.UserControl' in Assembly 'System.Windows.Forms ...    is not marked as serializable".  If i remove my usercontrol from my test form, then put a new one, i get the same error.   If i create a new form, voilà!  It work.

Why am i getting this serialization havoc?
How can i avoid it?
Does it mean that once a custom control is added to my forms, i can't modify my control anymore?  That wouldn't make much sense

Thanks for your help
0
Comment
Question by:cdebel
  • 5
  • 3
9 Comments
 
LVL 10

Author Comment

by:cdebel
ID: 40583336
Here's some part of my code

My List<ColumnItem> property

        private List<ColumnItem> mColumnsItems = new List<ColumnItem>();
        [Category("_MyControlProperties")]
        [Description("Define your grid headers")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        [Editor("System.Windows.Forms.Design.StringCollectionEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(CollectionEditor))]
        public List<ColumnItem> Columns
        {
            get
            {
                return mColumnsItems;
            }
        }

Open in new window


My ColumnItem Class

    public class ColumnItem
    {
        public float Width { get; set; }
        public string DBColumnName { get; set; }
        public string GridColumnName { get; set; }

        public DataGridViewContentAlignment Alignment { get; set; }
        public eColumnType ColumnType { get; set; }
        public bool Visible { get; set; }
        public int FilterPlaceholder { get; set; }

        public ColumnItem()
        {
            Width = 1;
            ColumnType = eColumnType.eNone;
            Alignment = DataGridViewContentAlignment.MiddleCenter;
            DBColumnName = "";
            GridColumnName = "";
            Visible = true;
            FilterPlaceholder = -1;
        }


        public override string ToString()
        {
            return DBColumnName;
        } 

Open in new window



ColumnItem have a constructor to initialize some values, and it has a ToString so the Editor can show the name i want in the list, otherwise its difficult to manage when all of them have similar names.
0
 
LVL 74

Assisted Solution

by:käµfm³d 👽
käµfm³d   👽 earned 150 total points
ID: 40583344
Do you have the Serializable attribute at the top of your class definition?

e.g.

[Serializable]
public class YourClass
{

Open in new window

0
 
LVL 10

Author Comment

by:cdebel
ID: 40583350
Another detail...

I've a solution with 3 project in it:
My "ComponentSuite" project
A project with test forms
Another project with test forms

Can it be linked to that?  Because it's in the same solution it get mixed up someway?  Because i've just closed Visual Studio 2010 because i was not able to add this control again without getting this error.  Then when i restarted VS, and added this control, the problem went away.

Next time it occur, i won't delete the object and just close VS and reopen it to see if it can get back on track, because i really can't delete every control of this app in every form and re-create them each time this error occur.
0
 
LVL 10

Author Comment

by:cdebel
ID: 40583353
kaufmed: [Serializable] shouldn't be used in this case.  I can't really explain if myself and i don't know if it's allowed to post link from other forums but here's the explanation i've found about this:

What you want is a design time support with CodeDom serialization. You do not need SerializableAttribute or ISerializable, those are for binary serialization. Since you want to serialize the collection, you must tell the designer to serialize it as such. That is done with the DesignerSerializationVisibiliby attribute - value of Content tells the designer to serialize property contents rather than property itself. Contents of the property should of course be CodeDom serializable, which simple classes with simple properties are by default.
0
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 40
ID: 40584312
What do you intend to achieve with         [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]

This is an instruction on how to generate the serialization code. This is probably why kaufmed suggested to make it Serializable. If you class is not Serializable, then this line is useless and this can create strange behavior.

Also, we do not see the whole code, but where and how do you use your custom control? Do you use is as a member in one of your own classes? When you drop it on a Form, is it on the Form itself or on a container Control?

System.Windows.Forms.UserControl' in Assembly 'System.Windows.Forms ...    is not marked as serializable usually implies that you are referencing your control in an object that is itself serializable. By default, in order to serialize an object, all its members must also be serializable.

Finally, when you show us something that you have found elsewhere, tell us where you found it. You might have found it in an article that has nothing to do with your situation.
0
 
LVL 10

Author Comment

by:cdebel
ID: 40591891
Jacques:

I've not been able to reproduce this problem yet.  I'll do some more tests (add methods and properties) to reproduce the problem and i'll test what kaufmed suggedted.  I think i've tested it, but i'm not sure if it was on my ColumnItem class.  I think it was on my user control itself.

To asnwer your questions...
How do i use my custom control? I drop it on the form itself, for the moment.

System.Windows.Forms.UserControl' in Assembly 'System.Windows.Forms .  Maybe it happen just because ColumnItem is not serialisable even if i thought it would be.  As i said, i thought it would be serialized because of  [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]  

And finally, the link where i've found that article: S.O. Article
0
 
LVL 40

Accepted Solution

by:
Jacques Bourgeois (James Burger) earned 350 total points
ID: 40592036
However, to be able to serialize a class, all of its members should also be serializable.

Reviewing your class, I see that the alignment member is a DataGridViewContentAlignment. This is an Enum, and enums are not serializable by default.

If it was a custom Enum, there are ways to declare it that enable serialization. But since it is a system enum, there is nothing you can do to make it serializable.

You could always implement the ISerializable interface and provide the serialization code yourself, but it is too much work simply for one member, which seems to be your problem at first sight.

In order to enable your class to be serializable without going through the implementation, you need to first give it the Serializable attribute, as pointed to by kaufmed. This tells the computer to do the job for you. But by default, this will fail because of your enum member.

The solution is to store the value of your property in an integer variable that will be serializable, and write a full property that will make the necessary cast in the get and the set. I have not tested it and I am more proficient in VB than in C#, but it would look something like the following:
		using System.ComponentModel;

		[EditorBrowsable(EditorBrowsableState.Never)] public int _Alignment;

		public DataGridViewContentAlignment Alignment
		{
			get
			{
				return (DataGridViewContentAlignment)_Alignment;
			}
			set
			{
				_Alignment = (int) value;
			}
		}

Open in new window

0
 
LVL 10

Author Comment

by:cdebel
ID: 40592091
Jacques:  Thanks for the pointer!   I'll try the conversion, or even just define my own alignment enum.
0
 
LVL 40
ID: 40592148
Your own enum will have the same problem by default.

Once again, it's an attribute that solves the problem (https://msdn.microsoft.com/en-us/library/vstudio/system.runtime.serialization.enummemberattribute%28v=vs.100%29.aspx).
0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

Does the idea of dealing with bits scare or confuse you? Does it seem like a waste of time in an age where we all have terabytes of storage? If so, you're missing out on one of the core tools in every professional programmer's toolbox. Learn how to …
Since upgrading to Office 2013 or higher installing the Smart Indenter addin will fail. This article will explain how to install it so it will work regardless of the Office version installed.
In this fifth video of the Xpdf series, we discuss and demonstrate the PDFdetach utility, which is able to list and, more importantly, extract attachments that are embedded in PDF files. It does this via a command line interface, making it suitable …
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

746 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now