Hummm ... not a workable design.
[quoted text, click to view] > My plan was that it the properties for ItemA or ItemB ever changed someone
> would just write a new class that inherits the old one and change the
> enumeration,
When the new class inherits from the old class (i.e. Item_A_Class or
Item_B_Class class) it will inherit the enumeration Properties also.
However, the new class will not be able to override the enumeration. It
will only be able to shadow the enumeration. This means that you will have
to completely duplicate the enumeration in each derived class. This
completely defeats a crucial purpose of object orientated design; code
re-use.
An enumeration is not an effective type for storing a list of items. The
call to get the element names in the enumeration is very slow. Using the
element names as the data storage is not what an enumeration is designed
for. There are many other types that implement the IList interface that are
more efficient at storing and retrieving items in a list. Use one of these
instead.
The manner in which you want to use one variable type (Dynamic_Class) to
access methods in two different types (Item_A_Class and Item_B_Class) is
known as polymorphism in object oriented design. In order for you to
implement this with your Item_A_Class and Item_B_Class classes you need
something common to both of them that the Dynamic_Class class can use to
access them. Currently there is nothing common in both classes. You may
think that and enumeration named Properties is common to both but consider
this; the system sees the enumerations as Item_A_Class.Properties and
Item_B_Class.Properties, two completely different enumerations.
So, how do we apply polymorphism to these classes? There is a method that
is slow and prone to run-time error. Simply make Dynamic_Class of type
Object. The Object type is common to all types. Then use late-binding to
access the Properties enumeration. For example,
Dim Dynamic_Class As Object = New Item_A_Class()
Dim properties as String() = _
System.Enum.GetNames(GetType( _
Dynamic_Class.Properties))
As I said above this is a very messy approach as there is no design-time or
compile-time type checking. Therefore, it is very easy for you or another
programmer to make errors that can not be caught until the project is
complied and the particular section of code is run. Also, error checking
late bound errors is generally a hellish experience as the compiler is only
able offer limited support.
As you add more item classes with even more enumerations this code will
become slower and even more prone to late-bound errors.
Do not dispair, there is hope. "We can rebuild [it]. We have the
technology." (Six Million Dollar Man, 1970s)
Anyway ... in order to cleanly get what you ultimately are seeking we need
to redevelope your design to take advantage of inheritance so polymorphism
and hence early-binding and strong type-checking with design-time support
can be applied. First we need to decide on a type to hold your property
data. As stated above any one of the types that implement the IList
interface will suffice. Since we do not want consumers of these objects to
modify, delete or add property names we will use an ArrayList. Now we can
define a class ItemBase that has a protected ArrayList and a public read
only Properties property.
Public MustInherit Class ItemBase
Protected _propertyNames As ArrayList
Public ReadOnly Property Properties() As ArrayList
Get
Return ArrayList.ReadOnly(_propertyNames)
End Get
End Property
End Class
We will make the ItemBase type common to all item classes through
inheritance.
Public Class ItemA
Inherits ItemBase
Public Sub New()
Dim names As String() = {"prop_1", "prop_2", "prop_3"}
_propertyNames = New ArrayList(3)
_propertyNames.AddRange(names)
End Sub
End Class
Public Class ItemB
Inherits ItemBase
Public Sub New()
Dim names As String() = {"prop_A", "prop_B", "prop_C"}
_propertyNames = New ArrayList(3)
_propertyNames.AddRange(names)
End Sub
End Class
Now we can use an ItemBase variable to access the common Properties property
of any item class.
Private Sub BuildPropertiesPanel(ByVal Item As String)
Dim ibProperties As ItemBase
Select Case Item
Case "ItemA"
ibProperties = DirectCast(New ItemA(), _
ItemBase)
Case "ItemB"
ibProperties = DirectCast(New ItemB(), _
ItemBase)
Case Else
Throw New ArgumentOutOfRangeException("Item", _
Item, "Unknown Item requested.")
End Select
Dim i As Integer
Dim alProperties As ArrayList = ibProperties.Properties()
For i = 0 To alProperties.Count - 1
'Build property panel
Console.WriteLine(alProperties(i).ToString())
Next
End Sub
The DirectCast is not needed if Option Strict is not activated (i.e.
ibProperties = New ItemA()).
Finally, through inheritance we can extend an item class to hold more
properties for an item.
Public Class ItemAEx
Inherits ItemA
Public Sub New()
MyBase.New()
Dim extraNames As String() = {"prop_4", "prop_5"}
_propertyNames.Capacity += 2
_propertyNames.AddRange(extraNames)
End Sub
End Class
Now change ItemA to ItemAEx in the BuildPropertiesPanel procedure to see the
new entries printed to the console.
Hope this helps.
Robby.
[quoted text, click to view] "David A. Osborn" <dosborn278@hotmail.com> wrote in message
news:haGEd.565$EG1.45@attbi_s53...
> Basically I have a series of classes that represent items in my program.
> These items all have different properties that need to be displayed in a
> property window. When the property window geta focus it will check to se
> what item is selected and dynamically build the label boxes on itself
> based on what the item is. How I've organized this is each item is its
> own class. In each class is an enumeration for that item which contains
> the properties for that particular item. So the properties panel needs to
> decide what class to use based on the string that is passed to it, and
> then loop through the enumerations to dynamically build labels on itself?
>
> I'm looking to do something like this. Obiviously this code/psuedo code,
> but hopefully it will portray the idea:
>
>
> Public Class Item_A_Class
> Public Enum Properties
> prop_1
> prop_2
> prop_3
> End Enum
>
> Some Funtions
>
> End Class
>
> Public Class Item_B_Class
> Public Enum Properties
> prop_A
> prop_B
> prop_C
> prop_D
> End Enum
>
> Some Functions
>
> End Class
>
>
> Private Sub Build_Properties_Panel (ByVal Item As String)