Hi Sorin,
Sorry for my delayed response. I have spent much time researching on how to
serialize the inner DataGridView's columns and finally I got it!
We need to implement a custom CodeDom serializer for the UserControl. The
custom CodeDom serializer derives from CodeDomSerializer class, which is in
System.ComponentModel.Design.Serialization namespace. We need to override
the Deserialize and Serialize methods in the custom CodeDom serializer
class.
Generally speaking, when we serialize a component, we use the base
serializer for the component to do it. Unfortunately, the base serializers
for both the DataGridViewColumnCollection and DataGridViewColumn instance
could not serialize them at all. So we have to serialize them by ourselves.
System.CodeDom namespace contains classes that can be used to represent the
elements and structure of a source code document. CodeDOM is often used by
designers to generate initialization code for component.
The following is the code of the custom CodeDom serializer.
public class MyCodeDomSerializer : CodeDomSerializer
{
public override object Deserialize(IDesignerSerializationManager
manager, object codeObject)
{
CodeDomSerializer baseClassSerializer =
(CodeDomSerializer)manager.GetSerializer(typeof(UserControl1).BaseType,
typeof(CodeDomSerializer));
return baseClassSerializer.Deserialize(manager, codeObject);
}
public override object Serialize(IDesignerSerializationManager
manager, object value)
{
CodeDomSerializer baseClassSerializer =
(CodeDomSerializer)manager.GetSerializer(typeof(UserControl1).BaseType,
typeof(CodeDomSerializer));
// serialize the UserControl
object codeObject = baseClassSerializer.Serialize(manager,
value);
if (codeObject is CodeStatementCollection)
{
CodeStatementCollection statements =
(CodeStatementCollection)codeObject;
// The code statement collection is valid, so add a comment.
string commentText = "This comment was added to this object
by a custom serializer.";
CodeCommentStatement comment = new
CodeCommentStatement(commentText);
statements.Insert(0, comment);
// serialize the inner DataGridView's columns
if (value is UserControl1)
{
DataGridViewColumnCollection innercolumns = (value as
UserControl1).InnerDGVColumns;
// declare the variable collection of columns in the
inner DataGridView
List<CodeVariableReferenceExpression> parameter_list =
new List<CodeVariableReferenceExpression>();
CodeArrayCreateExpression createArray = null;
CodeMethodInvokeExpression methodcall = null;
int i = 1;
CodeStatementCollection col_Statements = null;
foreach (DataGridViewColumn col in innercolumns)
{
/// serialize each column
col_Statements = new CodeStatementCollection();
CodeObjectCreateExpression col_ObjectCreate = new
CodeObjectCreateExpression(col.GetType());
CodeVariableDeclarationStatement
col_VariableDeclaration = new
CodeVariableDeclarationStatement(col.GetType(), "column" + i.ToString());
CodeAssignStatement col_Assign_Create = new
CodeAssignStatement(new CodeVariableReferenceExpression("column" +
i.ToString()), col_ObjectCreate);
// serialize the Width property of the column
CodeAssignStatement col_Assign_width = new
CodeAssignStatement(new CodeVariableReferenceExpression("column" +
i.ToString() + ".Width"), new CodePrimitiveExpression(col.Width));
CodeFieldReferenceExpression col_FieldReference =
base.SerializeToExpression(manager, col) as CodeFieldReferenceExpression;
if (col_FieldReference == null)
{
col_Statements.Add(col_VariableDeclaration);
col_Statements.Add(col_Assign_Create);
col_Statements.Add(col_Assign_width);
parameter_list.Add(new
CodeVariableReferenceExpression("column" + i.ToString()));
}
///
statements.AddRange(col_Statements);
i++;
}
CodeFieldReferenceExpression target =
base.SerializeToExpression(manager, value) as CodeFieldReferenceExpression;
// if the designer hasn't all the columns to the inner
DataGridView's column collection, add them by ourselves.
if (target != null && parameter_list.Count > 0)
{
createArray = new
CodeArrayCreateExpression(typeof(DataGridViewColumn),
parameter_list.ToArray());
methodcall = new CodeMethodInvokeExpression(new
CodeVariableReferenceExpression(target.FieldName + ".InnerDGVColumns"),
"AddRange", createArray);
statements.Add(methodcall);
}
}
}
return codeObject;
}
}
Adorn DesignerSerializerAttribute to the UserControl and
DesignerSerializationVisibilityAttribute to the property for the inner
DataGridView's columns.
[DesignerSerializer(typeof(MyCodeDomSerializer),typeof(CodeDomSerializer))]
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
[Editor(typeof(MyCollectionEditor),typeof(UITypeEditor))]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public DataGridViewColumnCollection InnerDGVColumns
{
get { return this.dataGridView1.Columns; }
}
}
I also send you with this reply a sample project that contains both the
custom UITypeEditor and CodeDom serializer. Please change the attachment's
file extension .JPG to .ZIP and unzip it on your machine.
Note: in the above sample code and the attached project, I only serialize
the Width property of a DataGridView column just for an example. I'm sure
you could serialize other proerties for the DataGridView column in the same
way.
Please try it and let me know if it is what you want.
Sincerely,
Linda Liu
Microsoft Online Community Support