Adding namespaces to code behind automatically (C#)

C

cpnet

I've authored a custom web component (a non-ui component kinda like a
DataSet) and so far it's working. When my web component is added to the web
form in the designer from the toolbox, the namespace for my component is
automatically added to the using directive of the codebehind. And, the
appropriate assembly is added to the "References" for the Web form's
project.

However, my custom component has a field (initialized to null, and exposed
by a public property. I see this assignment of the property to null is
automatically added to the InitializeComponent() method of the webform (I
don't know why this would be done). But, the type of this field/property is
a class that's in a different namespace, and different assembly, so my code
won't compile until I manually add this extra namespace to the webform's
using clause, and add the Reference to this second assembly. I need to make
sure that when my component is dropped on a webform, this additional
namespace is put in the code behind's using clauses, and that the additional
assembly is added to the project's 'references'. Or, I need to make sure
that this null assignment isn't repeated in the codebehind for the webform.
Then the user of my webcontrol can just manually add the 2nd namespace and
assembly reference if they actually make use of the property in question.

Any ideas?

Thanks
 
S

Steven Cheng[MSFT]

Hi Cpnet,

As for the adding dependent references and initializing "null" statement
problem you mentioned, here are my suggestions:

1. The VS.NET IDE will compare the value you set for the declaration of the
member field with its default value , if they're the same ,then it won't
add the null assignment in the initalizeComponent method. For example, in
the following component class, it contains a member
public class SimpleComponent : System.ComponentModel.Component
{
private ClassLib.UserName _userName = null;

[Browsable(true),
DefaultValue(null)]
public ClassLib.UserName UserName
{
.....
}
.............
}

we set the initialize value and the "DefaultValue" as the same value "null"
so that when we add the component onto our form, it won't repeat the null
assignment.

2. As for the denpendent assemblies reference, it is the normal behavior
that IDE will only add the component's main assembly. And if we need to let
the IDE auto reference all the denpendences for user when drag the
compoenent from toolbox onto form, we have to provide an additional class
which derived from the System.Drawing.Design.ToolboxItem class and override
its "CreateComponentsCore" function.
This class will do the operations needed when we drag a component onto a
form( do them in the "CreateComponentCore" function), and we need to apply
it to the component class via the "ToolboxItem" attribute , for example:
===================================
[ToolboxItem(typeof(ComponentLib.SimpleComponentToolboxItem))]
public class SimpleComponent : System.ComponentModel.Component
{
....

}

[Serializable]
public class SimpleComponentToolboxItem : System.Drawing.Design.ToolboxItem
{
....
}


And here is a complete demo I've used to test, you may have a look for
detailed reference:

=========ClassLib-------a separate class assembly=============
namespace ClassLib
{
/// <summary>
/// Summary description for Class1.
/// </summary>
public class UserName
{
private string _firstName = string.Empty;
private string _lastName = string.Empty;

public string FirstName
{
get
{
return _firstName;
}
set
{
_firstName = value;
}
}

public string LastName
{
get
{
return _lastName;
}
set
{
_lastName = value;
}
}

public UserName()
{

}

public UserName(string firstName, string lastName)
{
_firstName = firstName;
_lastName = lastName;
}
}
}
===================================
===========the component assemnbly================
namespace ComponentLib
{
/// <summary>
/// Summary description for SimpleComponent.
/// </summary>
///


[ToolboxItem(typeof(ComponentLib.SimpleComponentToolboxItem))]
public class SimpleComponent : System.ComponentModel.Component
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
private ClassLib.UserName _userName = null;


[Browsable(true),
DefaultValue(null)]
public ClassLib.UserName UserName
{
get
{
return _userName;
}
set
{
_userName = value;
}
}
public SimpleComponent(System.ComponentModel.IContainer container)
{
///
/// Required for Windows.Forms Class Composition Designer support
///
container.Add(this);
InitializeComponent();

//
// TODO: Add any constructor code after InitializeComponent call
//
}

public SimpleComponent()
{
///
/// Required for Windows.Forms Class Composition Designer support
///
InitializeComponent();

//
// TODO: Add any constructor code after InitializeComponent call
//
}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}


#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
#endregion
}

[Serializable]
public class SimpleComponentToolboxItem : System.Drawing.Design.ToolboxItem
{

public SimpleComponentToolboxItem() : base() {}

private SimpleComponentToolboxItem(SerializationInfo info,
StreamingContext context)
: base(typeof(SimpleComponent))
{
Deserialize(info, context);
}

protected override IComponent[] CreateComponentsCore(IDesignerHost host)
{

ITypeResolutionService service1;
Assembly assembly1,assembly2;

IComponent component1;
IComponent[] componentArray1;

IContainer container1 = host.Container;
service1 = ((ITypeResolutionService)
host.GetService(typeof(ITypeResolutionService)));

assembly1 = typeof(ClassLib.UserName).Module.Assembly;
assembly2 = typeof(ComponentLib.SimpleComponent).Module.Assembly;
service1.ReferenceAssembly(assembly1.GetName());
service1.ReferenceAssembly(assembly2.GetName());

component1 = new ComponentLib.SimpleComponent();
container1.Add(component1);
componentArray1 = new IComponent[]{component1};

return componentArray1;

}


}
}
==================================================

Then, you can try using the component class in a winform or webform project
and try to add it by dragging from toolbox. Both the "UserName"'s assembly
and the component's assembly will be added in the reference list.
You should pay attention to the "SimpleComponentToolboxItem's
CreateComponentsCore method where I put the referencing assembly code
there. If you have anything unclear, please feel free to post here.



Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)

Get Preview at ASP.NET whidbey
http://msdn.microsoft.com/asp.net/whidbey/default.aspx
 
J

John Saunders

Steven Cheng said:
Hi Cpnet,

As for the adding dependent references and initializing "null" statement
problem you mentioned, here are my suggestions:

2. As for the denpendent assemblies reference, it is the normal behavior
that IDE will only add the component's main assembly. And if we need to let
the IDE auto reference all the denpendences for user when drag the
compoenent from toolbox onto form, we have to provide an additional class
which derived from the System.Drawing.Design.ToolboxItem class and override
its "CreateComponentsCore" function.
This class will do the operations needed when we drag a component onto a
form( do them in the "CreateComponentCore" function), and we need to apply
it to the component class via the "ToolboxItem" attribute , for example:
===================================
[ToolboxItem(typeof(ComponentLib.SimpleComponentToolboxItem))]
public class SimpleComponent : System.ComponentModel.Component
{
...

}

[Serializable]
public class SimpleComponentToolboxItem : System.Drawing.Design.ToolboxItem
{
...
}


And here is a complete demo I've used to test, you may have a look for
detailed reference:

Steven,

I'm not the OP, but THANK YOU for this example. This is exactly the sort of
thing I've been looking for to give me an understanding of the design-time
environment beyond that discussed in books like "Developing ASP.NET Server
Controls and Components".

There really needs to be a book on the subject of the design-time
environment (both for Windows and Web Forms environments). Does anyone know
of such a book? It all needs to be pulled together in a way that separate
MSDN articles cannot, no matter how good the individual reference articles
may be.
 
S

Steven Cheng[MSFT]

Hi Cpnet,

Have you had a chance to check out the suggestions in my last reply or have
you got any further ideas on this issue? If there're anything else we can
help, please feel free to post here. Thanks.

Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)

Get Preview at ASP.NET whidbey
http://msdn.microsoft.com/asp.net/whidbey/default.aspx
 
C

cpnet

Sorry, I finally got to try this out tonight. It worked great for adding
the 2nd assembly reference, but I still can't figure out how to
(automatically) add the 2nd namespace to the using clause for the webform
that my component is added to. There must be a way to do this?

Thanks,
cpnet
 
S

Steven Cheng[MSFT]

Hi Cpnet,

Thanks for your followup. As for the adding "using XXXX" statement
automatically. I'm not quite sure whether this is possible since I haven't
found any similiar cases which doing such work when draging a control or
coponent onto the form at design-time. And generally the "using ...."
statement is likely determined by the project's type you created, for
example ,when you create winform project, the codebhind will have the using
statement for the winform related Namespace, while in web project , will
using the web related namespaces.
Anyway, I'll consult some further experts on this to see whether they can
provide any clues. I'll update you as soon as I've got any new infos
.Thank.s

Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)

Get Preview at ASP.NET whidbey
http://msdn.microsoft.com/asp.net/whidbey/default.aspx
 

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

Members online

Forum statistics

Threads
473,821
Messages
2,569,747
Members
45,726
Latest member
RaleighAll

Latest Threads

Top