Inheriting from UserControl...

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

I'm trying to create a C# composite control and have inherited
from UserControl. This new control contains 9 buttons with images on
them ( no text ).

Firstly, what is the best way to expose these 9 buttons to the
developers who will be using my control. I want them to be able to
change visibility, enablement, onClick etc for each button, but not be
able add any new buttons. I initially thought of exposing them as some
kind of fixed array, but wanted the opinions of those with more
experience. In the case of an array or collection, what is the correct
way of exposing this so it can be customised via the object inspector.

Secondly, if I want a specific icon/bmp to appear in the ToolBox for my
component, where must this icon/bmp be stored. I know I need to use
ToolboxBitmap(typeof(MyComponent), "MyComponentBitmap") attribute, but
can this exist in an image list or should it be placed somewhere else?
 
Dominique said:
I'm trying to create a C# composite control and have inherited
from UserControl. This new control contains 9 buttons with images on
them ( no text ).

Firstly, what is the best way to expose these 9 buttons to the
developers who will be using my control. I want them to be able to
change visibility, enablement, onClick etc for each button, but not be
able add any new buttons. I initially thought of exposing them as some
kind of fixed array, but wanted the opinions of those with more
experience. In the case of an array or collection, what is the correct
way of exposing this so it can be customised via the object inspector.

Pass them out as a collection the same way the toolbar does it with the
toolbar buttons.
Secondly, if I want a specific icon/bmp to appear in the ToolBox for my
component, where must this icon/bmp be stored. I know I need to use
ToolboxBitmap(typeof(MyComponent), "MyComponentBitmap") attribute, but
can this exist in an image list or should it be placed somewhere else?

As a resource I would say, although I haven't done it. Just add the bitmap
to your project and specify it's build action as resource.

Michael
 
Michael C said:
Pass them out as a collection the same way the toolbar does it with the
toolbar buttons.

OK, but what is the proper syntax for exposing this collection? I think I
will use an inherited ArrayList for simplicity.
 
OK thanks for that. I now have my collection appearing in the Property
inspector, but I cannot set each button's event from there. Is there
something else I need to do for this to be enabled?

Dominique.
 
Dominique said:
OK thanks for that. I now have my collection appearing in the Property
inspector, but I cannot set each button's event from there. Is there
something else I need to do for this to be enabled?

Have one event which passing in the button as an enum parameter.

Michael
 
Stefan said:
Hi,

simplicity.

You should use a HashTable, it will give you much better performance.

I'd just define my own collection in a case like this that does not need
performance. That way you can have the exact functionality you need.

Michael
 
I would take a completely different tack on this than the other
responders.

First, are sure that there will only ever by 9 buttons? Do they
indicate something specific? I can, for example, having them in a
three-by-three square, something like the text alignment buttons in
Visual Studio Designer. You know: "upper left", "middle left", "lower
left", "upper middle"... that sort of thing.

If that's the case, then I submit that you don't want to just expose
them in a collection. Sure, that's the easy way to do it, but what you
really want is to create a UserControl that returns an indication of
what position the user chose. If you expose the nine buttons in a
collection then you're showing your client classes _how_ you solved the
problem: you're exposing implementation.

If we're taking the position buttons user control as an example, then
what you really _want_ to do is expose an interface that says, "This
control allows the user to choose one of nine positions, but I'm not
telling you how it does that." So, I would make it expose events /
properties like this:

1. A "position" enumeration: TopLeft, MiddleLeft, BottomLeft, etc. It
should have a [Flags] attribute so that the positions can be combined.
2. A "position chosen" event (just one event) that carries in its event
arguments which position the user chose.
3. A method to set which positions the user is allowed to choose (via a
combination of the "position" enumeration).
4. A method to set which positions the user is allowed to see (via a
combination of the "position" enumeration).
5. Nine properties for each button property that you want to expose to
clients, for example, "TopLeftImage," "MiddleLeftImage", etc.

Yes, this is a whole lot more work, but the advantage is that your
callers don't know how the control does its job. You could change it
from buttons to a radio button list and the same interface would still
apply.

There are exceptions (the ToolBox being one), but as a general rule
it's bad form to allow clients to see inside your UserControl and get
directly at controls therein, because then that locks you into one
implementation, and doesn't allow for multiple UserControls that do the
same thing (implement the same interface) but do it in different ways
(look & feel).

If you do decide to go the easy way and just expose an ArrayList of
buttons or something, make sure that you take care not to give your
clients direct access to your inside structures so that they can
cheerfully add and remove buttons from your control without your
consent. If you want them to never be able to change how many buttons
there are (just their attributes), build the collection / array to
return every time your client asks for the button list. Clients will
still have access to the original buttons, but not your internal
collection structure.
 
responders.

I agree with Bruce if you have the time make it scalable as Bruce
explained.

To add to Bruce's thought you take it one step further and create your
own 'Button' Class inheriting from 'Button', here is a quick example I
created just to give you an idea of were to start:

namespace Sle.Control
{
[System.ComponentModel.DefaultProperty("Text"),
System.Web.UI.ToolboxData("<{0}:WebCustomControl1
runat=server></{0}:WebCustomControl1>")]
public class WebCustomControl1: System.Web.UI.WebControls.WebControl
{
private string text;

[System.ComponentModel.Bindable(true),
System.ComponentModel.Category("Appearance"),
System.ComponentModel.DefaultValue("")]
public string Text
{
get
{
return text;
}

set
{
text = value;
}
}

protected override void Render(System.Web.UI.HtmlTextWriter output)
{
output.Write(Text);
}
}
}


Happy Coding,

Stefan
C# GURU
www.DotNETovation.com

"You always have to look beyond the horizon and can never be complacent
-- God forbid we become complacent."

Jozef Straus
 
Bruce Wood said:
I would take a completely different tack on this than the other
responders.

You've misinterpreted my response. I wasn't suggesting to expose a
collection of actual command buttons. Instead I would create a simple class
with the properties desired and expose a collection of those. This still
hides the implementation underneath but avoids the situation of having
several related functions, eg ButtonPressed(index), ButtonColor(index) etc.

Michael
 
Back
Top