User Control Instance/DataGridView.Columns in Visual Studio Design

F

Fabrizio

Hi Linda,

I'm the last one who is writing but for sure not the last one facing this
problem. Could you please kindly send also to me the zip with the code sample?
My e-mail is fabrizio.bertussi ~a-t~ libero.it

Thanks in advance,
Fabrizio
 
G

Gary Rusher

Hi Linda,

I'am about to use your code and it seems to work fine, however i would
like to a the columnnames as class variables instead of
intializecomponent [method] variables.

Can you help, plz

Thanks
Gary Rusher
 
A

Ahmed Samy Moursi

Hi Linda,
I had the same problem as you do and I solved it the way that had been
presented but I have something different my DataGridView is bounded to a
binding source and every time the designer is loaded the columns that
come from the binding source is added again to the collection of columns
!!!??
This problem is driving me nut i would appreciate it if you can see
through it and give me some hints.

Thanks in advance.
 
M

MelGrubb

I am currently trying to work around this issue. I would appreciate it I
could get a copy of the sample solution you mentioned.

Thank you
melgrubb [at] live (dot) com

Linda Liu said:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top