This example builds an extender provider that acts as a control array. You can add and remove controls from the array at design time. The array provides an event handler shared by all of the controls much as VB 6 does. It also provides a control collection that your code can iterate over at run time. For example, you can loop through the controls to set their Enabled or Visible properties.
The ButtonArrayProvider implements an ArrayIndex property for Button controls. For example, suppose a form holds a ButtonArrayProvider named ButtonArrayProvider1 and a Button named Button1. Then if you select the Button, the Properties window displays a value named "ArrayIndex on ButtonArrayProvider1."
Set this property to a value greater than -1 to add the control to the array. Set it to -1 to remove it from the array. You can right-click the property in the Properties window and select Reset to reset the value to -1.
The following code shows how the provider works. The ProvideProperty attribute tells Visual Basic the name of the property that the provider will provide for client controls.
The object raises a Click event if any of its client controls generate a Click event.
It stores information about its client controls in IndexInfo objects stored in the m_IndexInfo hash table. The GetArrayIndex and SetArrayIndex routines get and set a client control's ArrayIndex value.
See the code for additional details.
|
Imports System.ComponentModel
<ToolboxBitmap(GetType(ButtonArrayProvider), _
"control_array.bmp"), _
ProvideProperty("ArrayIndex", GetType(Button)), _
DefaultEvent("Click")> _
Public Class ButtonArrayProvider
Inherits System.ComponentModel.Component
Implements IExtenderProvider
...
' When the user clicks one of the buttons
' in the control array, we raise this event.
Public Event Click(ByVal Index As Integer)
' Information about a button.
Private Class IndexInfo
Public ClientControl As Button
Public ArrayIndex As Integer
' Initialize ArrayIndex to the default value.
Public Sub New(ByVal client_control As Button)
ClientControl = client_control
ArrayIndex = -1
End Sub
' Return True if ArrayIndex is the default.
Public Function IsDefault() As Boolean
Return (ArrayIndex = -1)
End Function
End Class
' Information about our client controls.
Private m_IndexInfo As New Hashtable
' We can only extend buttons.
Public Function CanExtend(ByVal extendee As Object) As _
Boolean Implements _
System.ComponentModel.IExtenderProvider.CanExtend
Return TypeOf extendee Is Button
End Function
' Return this control's ArrayIndex.
<Category("Data"), _
DefaultValue("-1")> _
Public Function GetArrayIndex(ByVal client_control As _
Button) As Integer
' Get the button's IndexInfo if it exists.
Return GetIndexInfo(client_control).ArrayIndex
End Function
' Set this control's ArrayIndex.
<Category("Data"), _
DefaultValue("-1")> _
Public Sub SetArrayIndex(ByVal client_control As _
Button, ByVal array_index As Integer)
' Get this control's info.
Dim index_info As IndexInfo = _
GetIndexInfo(client_control)
' Set the new minimum value.
index_info.ArrayIndex = array_index
' Add or remove the IndexInfo if necessary.
AddOrRemoveIfNecessary(client_control, index_info)
End Sub
' Remove the control from the array.
<Category("Data")> _
Public Sub RemoveArrayIndex(ByVal client_control As _
Button)
' Set the control's index to the default -1.
SetArrayIndex(client_control, -1)
End Sub
' Handles client button Click events by raising our
' Click event, passing it the button's index.
Private Sub Client_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs)
' Get the client and its IndexInfo.
Dim client_button As Button = DirectCast(sender, _
Button)
Dim index_info As IndexInfo = _
GetIndexInfo(client_button)
RaiseEvent Click(index_info.ArrayIndex)
End Sub
' Return this control's IndexInfo.
Private Function GetIndexInfo(ByVal client_control As _
Button) As IndexInfo
' See if we have IndexInfo for this control.
If m_IndexInfo.Contains(client_control) Then
' We have IndexInfo for this control. Return it.
Return DirectCast(m_IndexInfo(client_control), _
IndexInfo)
Else
' We do not have IndexInfo for this control.
' Return a new default IndexInfo.
Return New IndexInfo(client_control)
End If
End Function
' Add or remove this IndexInfo if necessary.
Private Sub AddOrRemoveIfNecessary(ByVal client_control _
As Button, ByVal index_info As IndexInfo)
' See if the IndexInfo should be present but is not,
' or should not be present but is.
If index_info.IsDefault <> Not _
m_IndexInfo.Contains(client_control) Then
If index_info.IsDefault Then
' The IndexInfo should not be present but
' is.
m_IndexInfo.Remove(client_control)
RemoveHandler client_control.Click, _
AddressOf Client_Click
Else
' The IndexInfo should be present but is
' not.
m_IndexInfo.Add(client_control, index_info)
AddHandler client_control.Click, AddressOf _
Client_Click
End If
End If
End Sub
' Return an Collection holding
' the controls in the array.
Public Function Controls() As Collection
' Build the collection.
Dim result As New Collection
For Each index_info As IndexInfo In _
m_IndexInfo.Values
result.Add(index_info.ClientControl)
Next index_info
' Return the collection.
Return result
End Function
End Class
|