Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion GroupsVB SyntaxEnterprise DevelopmentDatabase AccessControlsCOMWin APICrystal ReportDeploymentGeneralGeneral 2
Related Topics
VB.NET / ASP.NETMS SQL ServerMS AccessOther Database ProductsMore Topics ...

VB Forum / General 2 / May 2004



Tip: Looking for answers? Try searching our database.

UserControl and a Collection as Property. How?

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
ClarkVent - 28 May 2004 00:54 GMT
I'm creating a custom UserControl "MyControl" (in VB5/6). I want to have
a property "MyProp" like this:

  MyControl.MyProp.Add
  MyControl.MyProp(1).Text = "text"
  MyControl.MyProp(1).Number = 0
  MyControl.MyProp.Remove 1
  etc...

Now I've searched quite a bit in the newsgroups and on the net in
general (and MS's MSDN), and all I could find so far is that this should
be solved with a Class Collection. However, nowhere could I find any
(code-) samples for this. Could anybody please direct me to a sample or
tutorial for this?

Thanks in advance.
Steve Gerrard - 28 May 2004 03:35 GMT
> I'm creating a custom UserControl "MyControl" (in VB5/6). I want to have
> a property "MyProp" like this:
[quoted text clipped - 12 lines]
>
> Thanks in advance.

'class module CProp:

Option Explicit

Private mTxt As String
Private mNum As Double

Public Property Get Txt() As String
   Txt = mTxt
End Property

Public Property Let Txt(RHS As String)
   mTxt = RHS
End Property

Public Property Get Num() As Double
   Num = mNum
End Property

Public Property Let Num(ByVal RHS As Double)
   mNum = RHS
End Property

'user control MyControl:

Option Explicit

Private mCol As Collection

Private Sub UserControl_Initialize()
   Set mCol = New Collection
End Sub

Public Function AddProp(Prop As CProp) As CProp
   Call mCol.Add(Prop)
   Set AddProp = Prop
End Function

Public Property Get Prop(IndexKey As Variant) As CProp
   Set Prop = mCol.Item(IndexKey)
End Property

Public Sub RemoveProp(IndexKey As Variant)
   Call mCol.Remove(IndexKey)
End Sub

Public Property Get PropCount() As Long
   PropCount = mCol.Count
End Property

'Form1:

Private Sub Command1_Click()

   With MyControl1

       Call .AddProp(New CProp)

       .Prop(1).Txt = "test"
       .Prop(1).Num = 123
       Debug.Print .Prop(1).Txt, .Prop(1).Num

       .RemoveProp (1)

   End With

End Sub
ClarkVent - 30 May 2004 23:11 GMT
Thank you for your answer.

That's *almost* what I want. The difference being that your solution is
this:

    MyControl1.AddProp(New CProp)
    MyControl1.Prop(1).Txt = "test"
    MyControl1.Prop(1).Num = 123
    MyControl1.RemoveProp 1

and I need this:

    MyControl1.Prop.Add            <=== Different!
    MyControl1.Prop(1).Txt = "test"
    MyControl1.Prop(1).Num = 123
    MyControl1.Prop.Remove 1       <=== Different!

reason being is that I need my control to be code-compatible with an
existing VB control. A lot of VB controls (like ListView, TreeView
TabStrip, etc) have collections as properties. The collection itself has
different properties/methods as the individual items. I figured out a
way to solve it (sort of) as follows:

  Public Property Get Prop( Optional indexKey as Variant ) as Variant
    If IsMissing(indexKey) Then
      Set Prop = myCollection
    Else
      Set Prop = myCollection.Item(indexKey)
    End If
  End Property

The problem here is that this doesn't expose any of the
properties/methods at design time.

Thanks,

CV

>>I'm creating a custom UserControl "MyControl" (in VB5/6). I want to
>
[quoted text clipped - 89 lines]
>
> End Sub
Steve Gerrard - 31 May 2004 00:47 GMT
> Thank you for your answer.
>
[quoted text clipped - 12 lines]
>      MyControl1.Prop(1).Num = 123
>      MyControl1.Prop.Remove 1       <=== Different!

Ah, now I see what you are after. That can be done too. You need to
define a collection class, and use some procedure attributes to get the
effect you want. Here it goes:

'Class module CProp

' same as before

'Class module CPropList

Option Explicit

Private mCol As Collection

Private Sub Class_Initialize()
   Set mCol = New Collection
End Sub

'use menu Tools / Procedure Attributes...
'click Advanced, and set the ProcedureID
'of the Item method to (Default)
'this allows the MyProp(1) syntax, which
'is really MyProp.Item(1)

Public Property Get Item(IndexKey As Variant) As CProp
   Set Item = mCol.Item(IndexKey)
End Property

Public Sub Add()
   mCol.Add New CProp
End Sub

Public Sub Remove(IndexKey As Variant)
   mCol.Remove IndexKey
End Sub

'use menu Tools / Procedure Attributes...
'click Advanced, and set the ProcedureID
'of the NewEnum method to -4.
'this will enable use of the For Each syntax
'for iterating the collection

Public Function NewEnum() As IUnknown
   Set NewEnum = mCol.[_NewEnum]
End Function

'user control MyControl:

Option Explicit

Private mPropList As CPropList

Private Sub UserControl_Initialize()
   Set mPropList = New CPropList
End Sub

Public Property Get MyProp() As CPropList
   Set MyProp = mPropList
End Property

'and then Form1:

Option Explicit

Private Sub Command1_Click()

   With MyControl1

       .MyProp.Add

       .MyProp(1).Txt = "test"
       .MyProp(1).Num = 123

       Debug.Print .MyProp(1).Txt, .MyProp(1).Num

       .MyProp.Remove 1

   End With

End Sub

I personally prefer a more flexible Add method, one that returns the
object, and allows passing an object to be added, as I used in the first
example. Also, I would want to add an optional Key parameter, so the
collection could be built with keys, which are often faster than
indexes.
ClarkVent - 31 May 2004 17:19 GMT
Perfect!!! That's *exactly* what I want! :)

Now why couldn't I find that anywhere on the net?

>>Thank you for your answer.
>>
[quoted text clipped - 102 lines]
> collection could be built with keys, which are often faster than
> indexes.
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.