Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

User Control Instance/DataGridView.Columns in Visual Studio Design

117 views
Skip to first unread message

Sorin Dolha

unread,
Dec 30, 2006, 12:42:00 PM12/30/06
to
I have a Windows Forms-based project in Visual Studio 2005, containing a
simple user control (class) and a form (class) that hosts an instance of the
user control.

The user control class contains (aggregates) a DataGridView instance (using
a private modifier). Also, within the user control class, I have a public
property that allows external entities (such as the main form) to access the
inner DataGridView instance like this:

public DataGridView InnerDataGridView
{
get { return this.innerDataGridView; }
}

I compile the project, then open the main form in design mode. It displays
the form that contains the user control instance, that contains the
DataGridView instance. In the Properties window, when I select the user
control instance in the form, I have all user control's public properties, as
expected, including the InnerDataGridView property which has a plus (+/-)
sign in front, allowing me to expand it to read or set properties of the
inner DataGridView instance.

Everything seems right until I try to click the ellipsis button (...) on the
Columns property of the inner DataGridView. This means, in the form I have
selected the user control instance, and in the Properties window I expanded
InnerDataGridView property, selected the Columns [sub-]property, and clicked
on the ellipsis button in the right side.

At this time, Visual Studio designer displays a "object reference not set to
an instance of an object" error in a simple modal message box, and offers no
other details, and this seems to happen within DataGridView (i.e. not in my
code), or I run into a architectural/design restriction which I wasn't aware
of.

(I tried also to create an InnerColumns property in the user control class
that maps to the InnerDataGridView.Columns to have the InnerColumns property
directly in the list of properties of the user control, but even if this way
I didn't receive the message box, and the grid columns editor/designer modal
dialog was open, it wouldn't allow me to create new columns - i.e. when
adding a new column it said that "at least one column doesn't have a
template" and didn't save the column. However, if possible, I don't want to
go through such workarounds for my issue, I think there should be a way to
make the first method work, without the InnerColumns property.)

Does anybody knows more about this issue - why does it happen, and more
important, how can I get over it? I want the end user of my user control
(which will be delivered in a library not in a form in the end) to be able to
set up columns in the inner grid by using the standard columns designer.

Thank you very much in advance,

--
Sorin Dolha, DlhSoft

RobinS

unread,
Dec 30, 2006, 5:19:11 PM12/30/06
to
I don't think you can do that with the DataGridView. Check out the
posting
in this group titled "DataGridView Modifier property does not work". I
think that's the same kind of issue, although all I can see is the
answer
from one of the MSFTies; my newsreader didn't pick up the original
message for some reason.

Robin S.
----------------------------------------------------
"Sorin Dolha" <sdo...@community.nospam> wrote in message
news:2B15D7FC-71C2-40E1...@microsoft.com...

Sorin Dolha

unread,
Dec 31, 2006, 6:13:01 AM12/31/06
to
Thanks. Although that discussion doesn't directly relate to a similar
scenario, it helped me understand that "by design" Microsoft may have ignored
to consider many scenarios especially for developers (that develop controls
for other developers).

I'll try to figure out a different way (architecture/design) to resolve my
problem.

Thanks,

--
Sorin Dolha, DlhSoft

Linda Liu [MSFT]

unread,
Jan 2, 2007, 5:45:21 AM1/2/07
to
Hi Sorin,

I have performed a test based on your description and did see the same
thing as you did. I spent several hours researching on this issue.

Yes, you're right. The message box displaying "object reference not set to
an instance of an object" error comes from the
DataGridViewColumnCollectionEditor class, which is the UI type editor of
the Columns property of the DataGridView. The reason why this error occurs
is that the Site property of the DataGridView is NULL. When the
DataGridViewColumnCollectinEditor queries for services, it can't find then
because its site is NULL.

Generally speaking, only components which are placed on the form designer
directly have their Site property set by the form designer host. In your
scenario, the DataGridView is contained within a UserControl. When the
UserControl is dragged&dropped onto a form, only the UserControl instance
has its Site property set, not the DataGridView instance within the
UserControl, i.e. the Site property of the DataGridView remains NULL.

So it seems that the only way to get the DataGridViewColumnCollectionEditor
to work properly is to set the Site property of the DataGridView instance
properly. To do this, we could add the DataGridView instance to the
container collection of the designer host.

The following is a sample code.

private class UserControl1:UserControl
{


public DataGridView InnerDataGridView
{
get { return this.innerDataGridView; }
}

private void UserControl_Load(object, EventArgs e)
{
if (this.DesignMode && this.innerDataGridView.Site == null)
{
this.Site.Container.Add(this.innerDataGridView);
}
}
}

Build the project and switch to the form designer. Now I could edit the
columns of the DataGridView contained in a UserControl using the
DataGridViewColumnCollectionEditor without any error occurring.

Unfortunately, when I run the program, I find that the columns I added at
design-time are missed at run-time. I have a look at the code in the
InitializeComponent method and find that a new DataGridView instance is
created and added to the UserControl and all changes I make using the
Properties window are made to the new DataGridView instance, rather than
the InnerDataGridView instance within the UserControl.

That's to say, my workaround works at design-time but the code
serialization is not what we want.

I will go on researching on how to get the code serialization to be what we
want. As soon as I have any new findings, I will get it back to you.

At the end, I susggest that you add a public property for the
DataGridView's Columns, something like the InnerColumns property you have
mentioned, and implement a custom collection editor based on
CollectionEditor class for the InnerColumns property.


Sincerely,
Linda Liu
Microsoft Online Community Support

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================

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

Linda Liu [MSFT]

unread,
Jan 5, 2007, 7:11:18 AM1/5/07
to
Hi Sorin,

After doing some more research, I am sorry that I haven't found a
workaround to get the code serialization to be what we want.

I still suggest that you implement a custom collection editor based on
CollectionEditor class for the DataGridView's Columns.

Linda Liu [MSFT]

unread,
Jan 18, 2007, 12:07:59 AM1/18/07
to
Hi Sorin,

Thank you for your feedback.

I am trying to implement a custom collection editor for the inner
DataGridView columns within a UserControl. The custom collection editor is
derived from CollectionEditor. The following is the code of the custom
collection editor.

using System.ComponentModel.Design;
using System.Windows.Forms;
class MyCollectionEditor:CollectionEditor
{
public MyCollectionEditor(Type type)
: base(type)
{ }

protected override Type CreateCollectionItemType()
{
return typeof(DataGridViewColumn);
}
protected override Type[] CreateNewItemTypes()
{
Type[] types = new Type[] { typeof(DataGridViewTextBoxColumn),
typeof(DataGridViewComboBoxColumn),
typeof(DataGridViewCheckBoxColumn),
typeof(DataGridViewButtonColumn),
typeof(DataGridViewImageColumn),
typeof(DataGridViewLinkColumn)};
return types;
}

protected override object CreateInstance(Type itemType)
{
DataGridViewColumn column =
itemType.GetConstructor(Type.EmptyTypes).Invoke(null) as
DataGridViewColumn;
return column;
}
}

We need to add an EditorAttribute on the inner DataGridView columns
property in the UserControl.

public partial class UserControl1 : UserControl
{
[Editor(typeof(MyCollectionEditor),typeof(UITypeEditor))]
public DataGridViewColumnCollection InnerDGVColumns
{
get { return this.dataGridView1.Columns; }
}
}

Thus, I could edit the columns for the DataGridView within the UserControl
at design-time. However, the problem is that the designer doesn't serialize
the code of the columns of the DataGridView after I add some columns into
the DataGridView at design-time.

I am thinking of using CodeDomSerializer to get the columns serialized
correctly. Unfortunately, I haven't worked it out yet.

I will go on researching on this and will get it back to you ASAP. I
appreciate your patience.

Sorin Dolha

unread,
Jan 18, 2007, 8:08:01 AM1/18/07
to
The code provided is absolutely great. I have tried the test project and it
seems to work as expected (that I see it's not visible here, on the
newsgroups, but I have received it on email, if someone wants it I can
re-send it)

I want to thank you very much for all the efforts you put into this.
Although for us it wasn't a feature that we needed so much that we couldn't
live without it in our project, now we can really implement it. (Of course,
with a few more changes related to column properties serialization - and I
need to do some testing to see if the serializer can use also custom
DataGridViewColumn-derived column types.)

Again, you have our deepest appreciation for all your help and support!

--
Sorin Dolha, DlhSoft


"Linda Liu [MSFT]" wrote:

> 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.

Linda Liu [MSFT]

unread,
Jan 19, 2007, 12:54:20 AM1/19/07
to
Hi Sorin,

Thank you for your prompt feedback.

The custom CodeDom serializer I provide should be able to serialize custom
DataGridViewColumn-derived column types.

Thank your for using our MSDN Managed Newsgroup Support Serive. 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 week end!

andylarson

unread,
Feb 19, 2007, 3:52:38 PM2/19/07
to
I too am struggling with this same problem and it appears you have found a solution. Could you possibly forward me the sample code so that I can implement this as well?

Thanks in advance,

Andrew Larson
Senior Application Developer
Turner & Associates
www.tacnet.com

EggHeadCafe.com - .NET Developer Portal of Choice
http://www.eggheadcafe.com

JP

unread,
Mar 6, 2007, 10:51:04 AM3/6/07
to
Is it possible to get the ZIP file containing the source code of the example ?

jpyerule ~AT~ hotmail.com

Thanks !
---
Posted via DotNetSlackers.com

Oral Coombs

unread,
Jun 26, 2007, 1:19:01 PM6/26/07
to
Linda,
Can you send me the sample project.
oralc...@hotmail.com

"Linda Liu [MSFT]" wrote:

Buamann@discussions.microsoft.com Siegmund Buamann

unread,
Oct 27, 2007, 8:18:01 AM10/27/07
to

Siegmund Buamann

unread,
Oct 27, 2007, 8:20:01 AM10/27/07
to
Hello Linda,

I ran into the same problem. Can you please send me your solution?

Kind regards
Siegmund Baumann

Patrick Finfrock

unread,
Nov 28, 2007, 2:32:56 PM11/28/07
to

I sure would like this solution as well. I have been working on this
for days. It is weird, I would think that usercontrols with DataGrid's
would be out there somewhere on the web.

Thanks

*** Sent via Developersdex http://www.developersdex.com ***

Thierry Monesma

unread,
May 9, 2008, 4:25:00 AM5/9/08
to
Hi Linda,

I would be pleased if you also send me the zip solution :)
I tried to copy paste the code in the current thread but some errors
still occurs when I drag-drop the user control on the main form (it
appears that the embedded datagridview is not instanciated on
serialization).

could you send it to me monesma -at- guidance.lu

Regards,
Thierry

Yagnesh Patel

unread,
May 28, 2008, 2:38:48 AM5/28/08
to
Hi Linda,
I also need this zip code file.

Can you please send me ?

Regards,

Yagnesh
yagnes...@conchango.com

Ferry Onderwater

unread,
Jul 1, 2008, 3:29:50 AM7/1/08
to
Hi Linda,

Could you please send me the code-example? The e-mail address is
M8R-1...@mailinator.com. Thank you in advance!!

Kind regards,

Ferry

Evgenia Nekrushets

unread,
Aug 13, 2008, 2:45:34 AM8/13/08
to
Hi Linda,

I ran into the same problem.

Could you please send me the code-example?

jw2...@mail.ru

Thank you in advance!

Regards,
Evgenia

Bon

unread,
Sep 24, 2008, 12:52:29 PM9/24/08
to
Hi Linda,

Just want to say thank you. This block of code have helped a lot in my
development. :)

Brajagopal Bhar

unread,
Oct 20, 2008, 2:51:39 AM10/20/08
to
Hello Linda,

I am facing the same problem. Can you PL send me the solution code at my
mail address given below:

brajagopal.bhar ~at~ tcs.com

Regards,

Brajagopal Bhar
TATA Consultancy Services Ltd

Peter Dieckmann

unread,
Nov 11, 2008, 3:56:04 AM11/11/08
to
Hello Linda,

Would you be so kind to send the sample code to me too since I am facing
the exact same problem?

pdieckmann ~a-t~ yahoo.com

I somehow get the impression that a lot of programmers are working on
this issue.
Therefore I would suggest to post the sample code somewhere where anyone
can access it.


Thank you very much in advance,

Peter Dieckman
Extedo GmbH

Fabrizio

unread,
Feb 12, 2009, 6:24:01 AM2/12/09
to
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

"Linda Liu [MSFT]" wrote:

> Hi Sorin,
>

Fabrizio

unread,
Feb 12, 2009, 6:26:02 AM2/12/09
to
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

Gary Rusher

unread,
Aug 10, 2009, 12:26:10 PM8/10/09
to

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

Ahmed Samy Moursi

unread,
Aug 30, 2009, 10:55:56 AM8/30/09
to
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.

Dhawal Shah

unread,
Dec 9, 2009, 5:36:38 AM12/9/09
to

I am also having tge same problem and seems like you have found a
solution. Can you also forward me the sample code as well?

Thanks in advance,


Family Tree Mike

unread,
Dec 9, 2009, 5:11:10 PM12/9/09
to

It would be easier to help you if we new what the original problem was.
What is the question? Your post is orphaned from the original question.

--
Mike

Armin Zingler

unread,
Dec 9, 2009, 5:24:13 PM12/9/09
to

Peter Hansson

unread,
Jan 8, 2010, 4:14:09 AM1/8/10
to

Can I please have the sample project.

I'm struggling with the same problem.

peter....@it-huset.se

Regards Peter

MelGrubb

unread,
Jan 22, 2010, 10:38:01 AM1/22/10
to
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 [MSFT]" wrote:

> Hi Sorin,
>

0 new messages