Adding a Custom User Control to a Form

M

Mark Olbert

I have a custom usercontrol which itself contains various other controls (e.g., textboxes).

When I add an instance of that custom control to a form, it "looks" just like it did in its own
designer.

But when I compile the application, the instance of the custom control on the form suddenly includes
duplicates of all the child controls that were included in the custom control's design.

Looking at the InitializeComponent() code shows that the custom control gets created and then later
added to the form's control collection:

this.giver_rec2 = new Test.giver_rec();
....
this.Controls.Add(this.giver_rec2);

But, in between those calls, when the custom control itself is being initialized, the following line
appears:

this.giver_rec2.Controls.Add(new DBFrameworkTextBox("lookup_key"));

which, of course, creates the duplicate control inside the custom control instance.

Has anyone run into this before?

- Mark
 
Y

Ying-Shen Yu[MSFT]

Hi Mark,


Do you mean the controls inside the user control was serialized into Form's
InitializeComponent?

Did you write a custom CodeDomSerializer for this user control?

If yes, Is it involved when serializing this usercontrol on the form?
I'd like to take a look at the code snippet of Serialize method.

If there is no customized codeDomSerializer for this usercontrol,
then is there anything special in this usercontrol or its designer?
(e.g. provide a new Controls collection, etc)





Please let me know more information on this issue if you still have problem
with it.

Best regards,

Ying-Shen Yu [MSFT]
Microsoft community Support
Get Secure! - www.microsoft.com/security

This posting is provided "AS IS" with no warranties and confers no rights.
This mail should not be replied directly, please remove the word "online"
before sending mail.
 
M

Mark Olbert

Do you mean the controls inside the user control was serialized into Form's
InitializeComponent? Yes

Did you write a custom CodeDomSerializer for this user control? No.

If there is no customized codeDomSerializer for this usercontrol,
then is there anything special in this usercontrol or its designer?
(e.g. provide a new Controls collection, etc)
That's a toughie to answer. I'm not creating anything like a new Controls collection, but I am
currently doing some funky things to deal with an issue I raised (and you answered) in another post,
involving getting the shadow property for an instance of the control in design mode.

Let me try implementing your suggestion in that post and see if the resulting simplification of the
custom control makes the problem go away.

- Mark
 
M

Mark Olbert

Ying-Shen,

The duplicate control was added to my custom user container control when the application compiled
because I was using a custom TypeConvertor for the control that was being duplicated.

Call the custom container control CustomContainer. Call the control that was being duplicated on
compile CustomControl. Every instance of CustomControl that was contained in CustomContainer was
being duplicated.

The TypeConvertor for CustomControl was defined to convert CustomControl to an InstanceDescriptor.
The constructor used for the InstanceDescriptor used a parameter. It was the existence of that
TypeConvertor which caused the problem. I'm not sure if it was due to not using a parameter-less
constructor in the InstanceDescriptor, or whether any InstanceDescriptor would've caused the
problem.

- Mark
 
Y

Ying-Shen Yu[MSFT]

Hi Mark,

Thanks for your reply!
Since you have narrowed down this problem to the type converter,
could you post some code snippet of the ConvertTo method?

I'd like to know what reference would you like to pass to constructor of
the custom component?

Is it a reference to a property of your custom container or another
component in the custom container?

Thanks!


Best regards,

Ying-Shen Yu [MSFT]
Microsoft community Support
Get Secure! - www.microsoft.com/security

This posting is provided "AS IS" with no warranties and confers no rights.
This mail should not be replied directly, please remove the word "online"
before sending mail.
 
M

Mark Olbert

Ying-Shen,

Here is the TypeConverter code:

public class DBFrameworkTextBoxConverter : TypeConverter
{
public override bool CanConvertTo( ITypeDescriptorContext context, Type destinationType )
{
if( destinationType == typeof(InstanceDescriptor) )
return true;

return base.CanConvertTo(context, destinationType);
}

public override object ConvertTo( ITypeDescriptorContext context, System.Globalization.CultureInfo
culture, object value, Type destinationType )
{
if( destinationType == typeof(InstanceDescriptor) )
{
ConstructorInfo tbxCtor = value.GetType().GetConstructor(new Type[] {
typeof(string) });
DBFrameworkTextBox theTBX = (DBFrameworkTextBox) value;

return new InstanceDescriptor(tbxCtor, new object[] { theTBX.FieldName });
}

return base.ConvertTo (context, culture, value, destinationType);
}
}

Again, I'm not sure if it was the existence of a TypeConverter for the custom control class, or
whether using a constructor that required a parameter in the TypeConverter that caused the problem,
but once I got rid of the TypeConverter (and rewrote my code so that the custom control class could
be created without that string parameter) the problem went away.

FYI, the custom control class (DBFrameworkTextBox) was a direct descendant of the standard TextBox
control.

- Mark
 
Y

Ying-Shen Yu[MSFT]

Hi mark,

I reproduced this issue on my system, after some investigation, It seems if
a control in the UserControl.Controls collection
which has a typeconvertor (which can convert to InstanceDescriptor)
defined will be serialized into Form1.InitializeComponent.
I'm contacting the product group to confirm if this is a correct behavior,
and will update the result to you soon.
In the mean time, I'd like to know if we have to add a string parameter in
the constructor? Is it possible to set it in the property?

Thanks!

Best regards,

Ying-Shen Yu [MSFT]
Microsoft community Support
Get Secure! - www.microsoft.com/security

This posting is provided "AS IS" with no warranties and confers no rights.
This mail should not be replied directly, please remove the word "online"
before sending mail.
 
M

Mark Olbert

Ying-Shen,

Setting the value as a property, and not using a TypeConverter, is essentially the workaround I
found. However, at the very least the "need" to not use a TypeConverter (or the "need" to use a
parameterless constructor if a TypeConverter is used) ought to be documented somewhere.

- Mark
 
Y

Ying-Shen Yu[MSFT]

Hi Mark,

After confirming with the product group, using typeconverter in this
scenario is supported. This issue seems like a bug in the Code
DOMSerializer, the product group will investigate it further to see if they
can fix it in the next release...

For now, we can workaround this issue by declaring a new Controls property
in your container usercontrol,

[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new ControlCollection Controls {
get { return base.Controls; }
}

as the attribute suggests, it will prevent the usercontrol code serializer
serialize the Controls collection.
It could be a workaround if the user control needn't act as a container
control when it is on a Form design surface.

If you have any questions on this issue, please feel free to reply this
thread.


Best regards,

Ying-Shen Yu [MSFT]
Microsoft community Support
Get Secure! - www.microsoft.com/security

This posting is provided "AS IS" with no warranties and confers no rights.
This mail should not be replied directly, please remove the word "online"
before sending mail.
 

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