Windows Develop Bookmark and Share   
 index > Windows Forms General > Does anyone know how to implement IComponent?
 

Does anyone know how to implement IComponent?

I am trying to implement IComponent rather than derive from Component becuase I wish to turn a (non-component) base class into a component (.NET does not support multiple inheritance - if it did I could simply derive from Component and my base class). However I can't overcome the "The base class'<base class name>'cannot be designed" error when I double-click the component and launch the default component designer. Please, does anyone know how to do this?

The following code sample is my implementation so far (for sake of simplicity the example does not explicitly derive from a base class - it implicitly derives from System.Object).

Component1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;

namespace Example
{
[System.ComponentModel.DesignerCategory("Component")]
public partial class Component1 : IComponent
{
private ISite m_Site;
private bool m_Disposed;

public Component1()
{
InitializeComponent();
}

public Component1(IContainer container)
{
container.Add(this);
InitializeComponent();
}

~Component1()
{
this.Dispose(false);
}

protected virtual void Dispose(bool disposing)
{
if (!this.m_Disposed)
{
if (disposing)
{
/* release managed resources */
if (components != null)
components.Dispose();
}

/* release native resource */

this.m_Disposed = true;

if (this.Disposed != null)
this.Disposed(this, EventArgs.Empty);
}
}

#region IComponent Members

public event EventHandler Disposed;

public ISite Site
{
get { return m_Site; }
set { m_Site = value; }
}

#endregion

#region IDisposable Members

public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}

#endregion
}
}

Component1.Designer.cs

namespace Example

{
partial class Component1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;

#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
}
}

Tim Douglas  Friday, October 24, 2008 3:29 PM
This worked:

using System;
using System.ComponentModel;

class MyComponent : SomeBaseClass, IComponent, IDisposable {
public event EventHandler Disposed;
ISite site;

MyComponent () {
}
~MyComponent() {
Dispose(false);
}
protected void Dispose(bool disposing) {
if (!disposing) return;
lock (this) {
if (site != null && site.Container != null) site.Container.Remove(this);
if (Disposed != null) Disposed(this, EventArgs.Empty);
}
}
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual object GetService(Type service) {
return site == null ? null : site.GetService(service);
}
public override string ToString() {
if (site == null) return base.GetType().FullName;
return (site.Name + " [" + base.GetType().FullName + "]");
}
protected virtual bool CanRaiseEvents {
get { return true; }
}
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public IContainer Container {
get { return site == null ? null : site.Container; }
}
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
protected bool DesignMode {
get { return site != null && site.DesignMode; }
}
public ISite Site {
get { return site; }
set { site = value; }
}
}

class SomeBaseClass { }
nobugz  Friday, October 24, 2008 6:09 PM

Your code does not work for me. You have forgotten to add the System.ComponentModel.DesignerCategory("Component") attribute to the class, but even with it added it still causes the "The base class 'System.Object' cannot be designed" error.

Are you sure your example appears as a component (not a class) in the solution explorer? And VisualStudio launches the Component designer when you double click the file?

FYI: I'm using Visual Studio Team System 2008 SP1

Thanks.

Tim Douglas  Tuesday, October 28, 2008 9:28 AM

The code produces the following error:

The designer could not be shown for this file because none of the classes within it can be designed. The designer inspected the following classes in the file: MyComponent --- The base class 'SomeBaseClass' cannot be designed. SomeBaseClass --- The base class 'System.Object' cannot be designed.

Tim Douglas  Tuesday, October 28, 2008 10:44 AM
Works fine when I try it, I can drag it from the top of the toolbox and drop it on a form. It looks and behaves just like a regular component. VS2008 SP1 Team Edition. Sounds like you're trying to do something else.
nobugz  Tuesday, October 28, 2008 12:03 PM

Indeed I am!

As stated in the original post "when I double-click the component [in the solution explorer] and launch the default component designer" the component cannot be designed. The only work-arround for this I have found isto derive from this component again - the default component designer then works fine.

In other words, the class implementing IComponent cannot be designed, but any derived class can be. Could this be a bug with Visual Studio?

Just so it's clear: I don't have problems placingthe component from the toolbox onto the design surface of another component. The problem is the other way round - I cannot open the designer of the component to place other components on its design surface.

Thanks in advance.

Tim Douglas  Thursday, November 06, 2008 8:34 AM
You cannot open the component in the designer unless you inherit Component. That's a hard requirement you cannot work around. The Component designer built into Windows Forms requires the Component base class. I can't see why this would be a hangup. All the designer does is add code, you can write that code yourself. If you don't know what to add, look at the code the designer generates on a regular Component.
nobugz  Thursday, November 06, 2008 1:49 PM

You can use google to search for other answers

Custom Search

More Threads

• How to determine if node exists
• DataRelation
• How to activate main form after splash screen
• .NET Wizard development support
• What is the best way to store client data
• TreeView Backcolor bug
• scrolling in listview
• Forms application development with an Sql Express database
• Closing a child form
• Multi monitors application