Creating Extender Providers

function OpenWin(url, w, h) { if(!w) w = 400; if(!h) h = 300; window.open(url, "_new", "width=" + w + ",height=" + h + ",menubar=no,toobar=no,scrollbars=yes", true); }

Extender Providers are created by implementing the IExtenderProvider interface. This interface has only a single method: bool CanExtend( object target ). This method is used to determine whether the provider can extend the target object. Generally, Extender Providers are designed to work only with specific types of components as in the case of the ToolTip Extender Provider. The ToolTip will only add the ToolTip property to Control-derived objects and will not extend MenuItems.

Adding properties to objects being extended is twofold. First the Extender Provider must use the ProvideProperty attribute. This attribute is applied to the Extender Provider class. Listing A.1 shows an example based on the ToolTip extender provider.

Listing A.1 Defining an Extender Provider
  1: [ ProvideProperty( "ToolTip", typeof ( Control ) ) ]  2: public class ToolTip : Component, IExtenderProvider {  3:  4:    //IExtenderProvider Interface Implementation  5:    bool IExtenderProvider.CanExtend( object target ) {  6:             if( target is Control )  7:               return true;  8:             else  9:               return false; 10:    } 11:  } 

The ProvideProperty attribute takes two arguments for its constructor. The first argument is the name of the property to provide. In the case of the ToolTip component, the property name happens to be ToolTip. Note that the name of the property being provided does not have to be the same as the name of the Extender Provider. Listing A.2 shows the start of the BorderPainterExtender component that will be developed as our first foray into Extender Providers.

Listing A.2 The BorderPainterExtender Class Description
  1: [ ProvideProperty( "BorderColor", typeof( Control ) ) ]  2: public class BorderPainterExtender : Component, IExtenderProvider {  3:  4:     //Implement the IExtenderProvider interface  5:     bool IExtenderProvider.CanExtend( object target ) {  6:         if( (target is Control) && !(target is Form) )  7:             return true;  8:         else  9:             return false; 10:  } 11: } 

The BorderPainterExtender will only extend controls hosted on a Form and will not provide a border to a Form-derived control. This brings up the second argument to the ProvideProperty attribute. In addition to the need to specify the name of the property to be provided, the base class or type of target being extended needs to be specified. In the case of the ToolTip and BorderPainterExtender, the target object must be of type Control.

With the basics of the BorderPainterExtender in place, you now need to understand how the property is added to the targets. The properties are provided via a set of method calls. These method calls allow for obtaining and setting the property value. The syntax for these methods is as follows:

 public type GetPropertyName( object target ) public void SetPropertyName( object target, type value ) 

PropertyName is replaced with the name specified within the ProvidePropertyAttribute. Notice that the properties are provided via method calls and not the property syntax. This is because the Extender Provider requires an additional parameter: the object associated with the property. When a ToolTip extender is placed on a Form, that single ToolTip extender provides the ToolTip property to every control on the Form. Hence only a single instance of the ToolTip is used to extend all the controls on the Form.

For a single extender to service all controls on the Form, the extender needs to track the provided property or properties for each control. This association can be accomplished by using a hashtable to map the control to its associated property. Listing A.3 extends the BorderPainterExtender to demonstrate this.

Listing A.3 Next Step in the BorderPainterExtender
  1: [ ProvideProperty( "BorderColor", typeof( Control ) ) ]  2: public class BorderPainterExtender : Component, IExtenderProvider {  3:  4:     protected Hashtable               borderColors;  5:  6:     public BorderPainterExtender( ) {  7:         borderColors = new Hashtable( );  8:     }  9: 10:     //Provide Get/Set methods 11:     public Color GetBorderColor( object target ) { 12:         return (Color)borderColors[ target ]; 13:     } 14: 15:     public void SetBorderColor( object target, Color color ) { 16: 17:         if( color.IsEmpty ) { 18:                borderColors.Remove( target ); 19:         }  else { 20:                borderColors[ target ] = color; 21:         } 22:     } 23: 24:      //Implement the IExtenderProvider interface 25:      bool IExtenderProvider.CanExtend( object target ) { 26:              if( (target is Control) && !(target is Form) ) 27:                return true; 28:              else 29:                return false; 30:    } 31: } 

The BorderPainterExtender has now been updated to associate the target object with a specified color. The methods GetBorderColor and SetBorderColor on lines 11 and 15, respectively, demonstrate how to expose the provided property. Again, the reason for this approach is that there exists only one instance of the extender and that extender will service all controls within the current Form.

During design-time, the property will be added to the list of properties available to the selected control. Figure A.1 shows the Property Browser with the BorderColor property added to the selected Label.

Figure A.1. The extended property BorderColor shown in the Property Browser.

figure a.1. the extended property bordercolor shown in the property browser.

Notice the BorderPainterExtender1 icon shown in the Icon Tray in Figure A.1. Extender Providers can be added to the Toolbox and used during design-time. In addition, notice the name of the property: BorderColor on BorderPainterExtender1. This property name comes from the fact that there may be another BorderPainterExtender added to the form. A way to distinguish which extender is hosting the property is necessary.

Note

To add an extender to the Toolbox, create a .NET dll assembly containing the extender. Next, customize the Toolbox and load the .NET dll assembly just as you would any other assembly. The extender will then be available in the Toolbox. This is how the ToolTip extender is provided.


To complete the BorderPainterExtender component, the BorderPainterExtender will monitor two mouse events: MouseEnter and MouseLeave. These events will be used to determine which control to paint a border around. The complete listing is shown in Listing A.4.

Listing A.4 Complete Implementation of the BorderPainterExtender
  1: [ ProvideProperty( "BorderColor", typeof( Control ) ) ]  2: public class BorderPainterExtender : Component, IExtenderProvider {  3:  4:     protected Hashtable    borderColors;  5:     protected Control        activeControl;  6:     protected Rectangle    borderRect;  7:  8:     public BorderPainterExtender( ) {  9:         borderColors    = new Hashtable( ); 10:         borderRect        = new Rectangle( ); 11:         activeControl    = null; 12:     } 13: 14:     bool IExtenderProvider.CanExtend( object target ) { 15:         return ((target is Control) && !(target is Form)); 16:     } 17: 18:     public Color GetBorderColor( object target ) { 19:         try { 20:             return (Color)borderColors[ target ]; 21:         }  catch( Exception ) { 22:             return new Color( ); 23:         } 24:     } 25: 26:     public void SetBorderColor( object target, Color color ) { 27: 28:         if( color.IsEmpty ) { 29:  borderColors.Remove( target ); 30:             ((Control)target).MouseEnter -= new EventHandler( OnMouseEnter ); 31:             ((Control)target).MouseLeave -= new EventHandler( OnMouseLeave ); 32:             if( target == activeControl ) 33:                 EraseBorder( ); 34: 35:          }  else { 36: 37:             if( !borderColors.Contains( target ) ) { 38:                  ((Control)target).MouseEnter += new EventHandler( OnMouseEnter ); 39:                  ((Control)target).MouseLeave += new EventHandler( OnMouseLeave ); 40:             } 41:             borderColors[ target ] = color; 42:             if( activeControl == target ) 43:                 DrawBorder( ); 44:         } 45:     } 46: 47:     protected void EraseBorder( ) { 48:         DrawRectangle( activeControl.Parent.BackColor ); 49:     } 50: 51:     protected void DrawBorder( ) { 52:         borderRect = new Rectangle( activeControl.Left, activeControl.Top, 53:                              activeControl.Width, activeControl.Height ); 54:         borderRect.Inflate( 2, 2 ); 55: 56:         DrawRectangle ( (Color)borderColors[ activeControl ] ); 57:     } 58: 59:     protected void DrawRectangle( Color color ) { 60:         Pen      borderPen = new Pen( color, 2 ); 61:         Graphics g         = activeControl.Parent.CreateGraphics( ); 62: 63:         g.DrawRectangle( borderPen, borderRect ); 64:         g.Dispose( ); 65:         borderPen.Dispose( ); 66:     } 67: 68:     protected void OnMouseEnter( object sender, EventArgs e ) { 69:         activeControl = (Control)sender; 70:         DrawBorder( ); 71:     } 72: 73:     protected void OnMouseLeave( object sender, EventArgs e ) { 74:         EraseBorder( ); 75:         activeControl = null; 76:  } 77: } 

To understand how the BorderPainterExtender works, locate the SetBorderColor method located on line 26. This method serves two purposes. First, if the color passed in is uninitialized, the target object is removed from the collection and the mouse event handlers are also removed. Otherwise, the color is associated with the target and the mouse events are monitored. Now, whenever the mouse enters a control being extended by the BorderPainterExtender, a border of the specified color is drawn around the control.

In addition to drawing a border around the control, when the mouse moves out of the control the border will be removed. Figure A.2 shows the BorderPainterExtender in action.

Figure A.2. Label with a red border provided by the BorderPainterExtender.

figure a.2. label with a red border provided by the borderpainterextender.

The association between the extender and a target happens when the provided property, in this case BorderColor, is set within the Property Browser for a given control. Remember that when an extender is added to a form, all target controls will have the specified property added to them. However, the association occurs only if the property value is set. If the property value is deleted or nulled out, the association will also be removed.

Extender Providers are flexible mechanisms for adding properties to .NET components. Any object in .NET can be an Extender Provider, even a control.



    .NET Windows Forms Custom Controls
    User Interfaces in VB .NET: Windows Forms and Custom Controls
    ISBN: 1590590449
    EAN: 2147483647
    Year: 2002
    Pages: 74

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net