473,703 Members | 2,355 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Custom Collection Class woes

I'm in the process of expanding my knowledge and use of Class Modules.
I've perused MSDN and this and other sites, and I'm pretty comfortable
with my understanding of Class Modules with the exception of custom
Collection Classes.

Background: I'm developing an A2K .mdb to be deployed as an .mde at my
current job-site. It has several custom controls which utilize custom
classes to wrap built-in controls, and add additional functionality. In
my job, I'm only at this site for about another year, and I'd like for
the folks that follow me here to be able to add the same custom
controls with minimal effort on forms they may need to construct down
the road. Making them a custom class also reduces the repetition of
reinventing them for every form I construct.

Details on the controls:

Type1 is an image control that acts like a command/toggle button. The
control has three states and is used to call code to bring up the
Office Assistant to serve a WhatsThis type function. That functionality
doesn't require a compiled help file, but gets its display inputs from
the database itself. This control has three states. Initially it is
flat with a dimmed image. OnMouseMove it is raised with a clear image.
OnClick it is armed for Assistant calls, and the image is sunken with a
dark image. On subsequent Clicks, the Assistant goes away, and the
button returns to its raised state. OnMouseOut which is simulated using
ctl.Section.OnM ouseMove, the button returns to its default, flat,
state.

Type2 is a label control that acts like a hyperlink. It has similar
OnMouseMove, OnMouseDown, and OnMouseUp functionality to Type1 and also
utilizes ctl.Section.OnM ouseMove to simulate MouseOut behaviour.

Both types are associated with existing controls using this code in the
form that utilizes them:

************
' Declarations section
************
Public/Private mclsControlX as CustomClass
' Public for Type1 to allow the Assistant to
' change the state of the control when
' cancelled and Private for Type2.
************
' Form_Load code
************
Set mclsControlX = New CustomClass
Set mclsControlX.Co ntrol(x, y) = ctlControlOnFor m

Problem 1: After reference to the aforementioned sources, I've been
able to create a custom Collection Class that wraps the built-in
Collection type. What I've been unable to do is assign all the
CustomClass objects to the same Collection. I've tried establishing a
reference to the collection in the CustomControl.C ontrol Property Set
procedure, but this has failed. I use this code for that Property Set:

************
' CustomClass module
************
Public Property Set Control(x ..., y ..., img as Image)
....
Dim col as CustomCollectio n
Set col = New CustomCollectio n
col.ClsControls .Add img, img.Name

The Initialize and Terminate events for the CustomCollectio n fire every
time this Property Set code runs and the Collection is neither singular
(collecting every control of TypeX), nor persistant. How do I make the
Collection both singular and persistant?

I tried using:

If col.ClsControls .Count > 0

But, that throws object Error 91 every time because this instance of
the CustomCollectio n hasn't been created, yet.

How do I set this CustomCollectio n up to wrap a built-in Collection and
become a container for all CustomClass objects of Type1 or Type2,
respectively?

Problem 2: I can't really tell when the Terminate event for the
CustomClass objects is firing. Since I don't want to leave unassociated
or dormant Class objects laying around in memory, I have been setting
the module level object variable that contains the reference to these
objects to Nothing in the Terminate event. Do I need to remove that
reference with the Nothing keyword to the Form_Unload event where the
controls are instantiated or is the Terminate event of the Class
sufficient?

Hope that's descriptive enough. If not, I'll try to clear the fog
wherever there is any.

Thanks in advance.

Jamey Shuemaker

Feb 19 '06 #1
19 4911
"Jamey Shuemaker" <ca*********@ya hoo.com> wrote:

************
' CustomClass module
************
Public Property Set Control(x ..., y ..., img as Image)
...
Dim col as CustomCollectio n
Set col = New CustomCollectio n
col.ClsControls .Add img, img.Name

The Initialize and Terminate events for the CustomCollectio n fire every
time this Property Set code runs and the Collection is neither singular
(collecting every control of TypeX), nor persistant. How do I make the
Collection both singular and persistant?


I'm not sure what "ClsControl s" and "CustomCollecti on" are supposed
to be. I'll go out on a limb here and assume the following:

1. You intended to create a Collection called "col" (a custom collection.)
2. You want to populate your collection with objects of the type described
in ClsControls (the code for which you have not posted.)

Assuming I got that right, then I suggest the following:

'The collection must be at the module level, or else it will
'vanish as soon as your Property Set procedure exits.

Private col as new Collection 'Module-level declaration

Public Property Set Control(x ..., y ..., img as Image)
'...
dim objClsControls as new ClsControls 'Declare object

'Set object properties (x? y? img?)
set objClsControls. img = img
set objClsControls. x = x
set objClsControls. y = y

'Now add the object to the collection, using the image
name as the collection key. Explicitly coerce it to a
string, just for good measure.

col.add objClsControls, cstr(img.name)
'...
end property


Feb 19 '06 #2
Sorry about that, here's the old code from the Collection Class Module:

*********
' Class Module named CollectionClass
*********
Private mCol as Collection

Public Property Set ClsControls(col as Collection)
Set mCol = col
End Property

Public Property Get ClsControls as Collection
Set ClsControls = mCol
End Property

*********

The object props above are actually:

x = A long integer that accompanies an Enumeration at the beginning of
the module to set the Type of the Class. In this case, it's always zero
(0) because I've only begun working with one type of image control
(button). I've envisioned several other custom buttons (spinner
buttons, custom navigation buttons, etc.) that behave slightly
differently than this Case 0.

y = A Section object, in this case, the section in which the control
resides. This is used by a module level object variable "mSct" to
handle the MouseOut type events I mentioned above.

img = This is the reference to the actual control that will be
associated with the custom Class.

The first code snipet above is the code from the Form's module, in this
case just the Type1 custom Class:

*********
' Declarations
*********
Public mclsControlX as CustomClass

*********
' Form_Load
*********
Set mclsControlX = New CustomClass
Set mclsControlX(0, Me.Section(Me!c tlControlOnForm .Section)) = _
Me!ctlControlOn Form

*********

The second code snipet above is from the custom Class Module, where I
was instantiating this element of the collection:

*********
' Declarations
*********
Private WithEvents mImg as Image
Private WithEvents mSct as Section

Enum BtnType
sbCSH = 0
sbIncrement = 1
....
sbClose = 7
End Enum

*********
' Property Set and Get to wrap built-in Image control
*********
Public Property Get Control(lngType as BtnType, _
sct as Section, img as Image)
Set mImg = img
With mImg
.OnMouseMove = "[Event Procedure]"
.OnClick = "[Event Procedure]"
.SpecialEffect = 0
End With
....
Set mSct = sct
mSct.OnMouseMov e = "[Event Procedure]"
....
' More code to set the three image paths
' so that mImg.Control.Pi cture can be
' changed later with state changes.
....
Dim col as New CustomCollectio n
col.ClsControls .Add img, img.Name
End Property

Public Property Get Control(lngType as BtnType, _
sct as Section) as Image
Set Control = mImg
End Property
*********

I've had something similar to what you suggested, but I'll try it
exactly like that. Whatever the case, I haven't been able to maintain
the persistance of the Collection Class, at least not where I can know
how to reference it.

As a side note, I know that my custom Class Objects are persisting
longer than I want them to, because once they are referenced to the
actual physical control on the form, if I try to delete that physical
control, the DB shuts down, abnormally. I'm not sure where my Scope
problems are, but I assume that I'll have to start removing those
references in Form_Unload.

Feb 20 '06 #3
Got it working by populating the collection in the Form's module. I
thought you could do the same by calling it in the Class Module for the
custom class, but I suppose that's not the case. Maybe if there were a
way to call it without using the New keyword, it could be done at Class
Module level, but I can't figure a way to do it.

Still have some Scope concerns. Any suggestions?

Feb 20 '06 #4
"Jamey Shuemaker" <ca*********@ya hoo.com> wrote:

I've had something similar to what you suggested, but I'll try it
exactly like that.
Well, I only suggested that based on a wild guess about what
you are trying to do. Now that you have posted more code,
I must shamefully admit that I'm lost. I have enough trouble
figuring out my _own_ code sometimes, and even more so
when reviewing something online.
Whatever the case, I haven't been able to maintain
the persistance of the Collection Class, at least not where I can know
how to reference it.
All I can suggest is that you carefully review the scope on your
object declarations. If your CollectionClass objects are vanishing,
then they are almost certainly going out of scope.
As a side note, I know that my custom Class Objects are persisting
longer than I want them to, because once they are referenced to the
actual physical control on the form, if I try to delete that physical
control, the DB shuts down, abnormally. I'm not sure where my Scope
problems are, but I assume that I'll have to start removing those
references in Form_Unload.


Hmm. Good luck with that.
Feb 20 '06 #5
rkc
Jamey Shuemaker wrote:
Got it working by populating the collection in the Form's module. I
thought you could do the same by calling it in the Class Module for the
custom class, but I suppose that's not the case. Maybe if there were a
way to call it without using the New keyword, it could be done at Class
Module level, but I can't figure a way to do it.
Your collection was declared and instantiated within a property
procedure. It's scope begins and ends in the procedure.
Still have some Scope concerns. Any suggestions?


Explicitly set all object (controls in your case) variables set
in your class modules to nothing in the Class_Terminate procedure.

Explicitly set the collection in the Form's module to nothing in
Form's Close event.

One of the Terry's (or Trevor's) that posts here suggests actually
removing all objects from the collection. Whichever it was doesn't
do a lot of talking through his hat so I do that now also.

Don't edit wrapped controls after running code without doing a
Debug -> Break -> Reset first.

Feb 20 '06 #6
rkc
It was Terry Kreft.

In a nutshell:

Private m_MyBooks As Collection
' *************** *************** ******
'

Private Sub Class_Initializ e()
Set m_MyBooks = New Collection
End Sub

Private Sub Class_Terminate ()
Do Until m_MyBooks.Count = 0
Call m_MyBooks.Remov e(1)
Loop
end sub
Feb 20 '06 #7
"Jamey Shuemaker" <ca*********@ya hoo.com> wrote in
news:11******** **************@ z14g2000cwz.goo glegroups.com:
Got it working by populating the collection in the Form's module.
I thought you could do the same by calling it in the Class Module
for the custom class, but I suppose that's not the case. Maybe if
there were a way to call it without using the New keyword, it
could be done at Class Module level, but I can't figure a way to
do it.

Still have some Scope concerns. Any suggestions?


Well, I'm very confused by all the things you've posted. I don't
understand any number of things:

1. are you creating a new instance of the class for each instance of
your custom control? If so, then I must have misunderstood what
you're doing, since each instance of the class would have only one
member in its internal collection.

2. you originally said you were working with a class wrapper around
a custom collection. That would mean that you'd want to use the same
class instance for all the items you are adding to your collection.
As you know, a custom class cannot be a public member of a class
module, so you have to create a wrapper around the collection to
populate it and clear items from it.

3. for a class instance to be used in multiple forms, the variable
used to refer to that class instance has to be publicly available at
all times. That means you either make it a public member of class
omdule or as a public member of a form that is always open. I'd
think that the former is easier than the latter, but I could see
circumstances where you'd do that latter (a form is, after all, just
a class module with a user interface included along with it).

4. if you declare your class variable with the NEW keyword, any call
to the class instance will initialize it. If you *don't* declare it
with the NEW keyword, you must initialize the class module before
using it. This can be done in startup code, or it could be done in
the OnOpen events of each form that uses the class instance (by
checking if it's Nothing and initializing if it is; that could
easily be put in a public function somewhere).

Now, those are all things that have an effect on scope, and if I've
understood what you're trying to do, you're simply declaring the
variable for your class instance in the wrong place.

But, as I said, I was very confused by what you've posted, so all of
what I"ve written above may be useless to you.

--
David W. Fenton http://www.dfenton.com/
usenet at dfenton dot com http://www.dfenton.com/DFA/
Feb 20 '06 #8

rkc wrote:
Private m_MyBooks As Collection
' *************** *************** ******
'

Private Sub Class_Initializ e()
Set m_MyBooks = New Collection
End Sub

Private Sub Class_Terminate ()
Do Until m_MyBooks.Count = 0
Call m_MyBooks.Remov e(1)
Loop
end sub


Yeah, that's one of the resources I started with. See below for details
of where I stand now. Looks like I've got it solved.

Feb 21 '06 #9
UPDATE:

First off, thanks for the help and sorry for the confusion. I though I
described the problem fairly well, but looking back, I guess I jumped
around a bit.

*********
' CustomCollectio n Class Module
*********
Private mCol as Collection

Public Property Set ColControls(col as Collection)
Set mCol = col
End Property

Public Property Get ColControls as Collection
Set ColControls = mCol
End Property

Private Sub Class_Terminate ()
Do Until mCol.Count = 0
mCol.Remove 1
Loop
Set mCol = Nothing
End Sub

*********
' CustomControl Class Module
*********
Private WithEvents mImg As Image
Private WithEvents mSct as Section
Private mlngType as BtnType

Enum BtnType
sbCSH = 0
sbIncrement = 1
...
sbClose = 7
End Enum

Public Property Set Control(lngType as BtnType, _
sct as Section, img as Image)
Set mImg = img
With mImg
.OnMouseMove = "[Event Procedure]"
' Other display settings
...
End With
Set mSct = sct
mSct.OnMouseMov e = "[Event Procedure]"
mlngType = lngType
' Set other display attributes by Type
....
End Property

Public Property Get Control(lngType as BtnType, _
sct as Section) As Image
Set Control = mImg
End Property

Private Sub Class_Terminate ()
Set mImg = Nothing
End Sub

Private Sub mImg_Click()
' Some code to execute OnClick
End Sub

Private Sub mSct_MouseMove( ...)
With mImg
' Code to reset default display attributes
End With
End Sub

*********
' Form Module Declarations
*********
Private mclsCol as CustomCollectio n
Public mclsBtn0 as CustomClass
Private mclsBtn1 as CustomClass

*********
' Form Module Code
*********
Private Sub Form_Load()
With Me
Set mclsCol = New CustomCollectio n
Set mclsBtn0 = New CustomClass
Set mclsBtn0.Contro l(0, .Section(.ctlOn Form.Section)) = _
.ctlOnForm
mclsCol.ColCont rols.Add .ctlOnForm, _
.ctlOnForm.Name
Set mclsBtn1... ' Same as above
End With
End Sub

Private Sub Form_Unload(Can cel as Integer)
Set mclsCol = Nothing
Set mclsBtn0 = Nothing
Set mclsBtn1 = Nothing
End Sub

*********
' End Code
*********

Questions that remain:

Am I adequately killing off all the custom class objects with the
Terminate events and the Form_Unload procedure? Do I need to enumerate
through all elements of the Form module level "mclsCol" object variable
and use the Remove method to get them out of memory, as well?

Do I need something like this in the Initialize event for each custom
class?

*********
Private Sub Class_Initializ e()
Set mCol = New Collection
End Sub
*********

Thanks again.

Feb 21 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
2188
by: rufus | last post by:
Hi, I have a custom collection class that inherits from HashTable. When I add a new CustomObject to my CustomCollection I would like to ensure that it will only accept objects of type CustomObject. How would I do this? Thanks in advance. Public Class CustomCollection Inherits Hashtable ' default constructor
0
1928
by: Sundown | last post by:
I am trying to create a custom button control for the web that, when clicked, disables and changes the text of itself and a bunch of other controls (in the collection). My goal is to end up with a button that prevents the user from submitting a form back multiple times and also prevents them from submitting the form and then clicking something else before the postback can finish processing. What I have is a working button that disables...
3
7001
by: Anthony Bouch | last post by:
Hi I've been reading using the XmlSerializer with custom collections. I've discovered that when serializing a custom collection (a class that implements ICollection, IList etc.) the XmlSerializer will only serialize the collection items - with the default root as ArrayofMyItems etc. My custom collection class has some additional public properties that I would like to include in the serialization above the items element array (in
8
3189
by: Tinus | last post by:
Hello all, I've create a custom control (UserControl) and have a custom Item Collection. The control is a custom calendar which is draw using the Graphics Rectangle etc. functions. It is drawn when the control is painted or resized. When the control is drawn it draws also the items found in the collection. So far so good.... I have 3 questions which I'm unable to find a solution
1
1409
by: Jeff S | last post by:
I'm storing a list of widgets in a database. The list changes infrequently (twice per week at most), and is relatively short (200 items at most, with very little detail per item). A small subset of all possible widgets will be displayed on a page (using VB.NET/code behind). I plan to populate a custom collection/class with a list of all possible widgets. The class will include a method that returns the required subset. Of course the logic...
3
1357
by: Matthias S. | last post by:
Hi there, I have a typesafe collection in my application called Countries, which is derived from the ReadOnlyCollectionBase. As you might guess, the item-value is of type Country. Each Country has (for now) and ID and a Name property. Now I'd like to use a CheckBoxList to display the contents of my Countries collection and let the user select some:
2
2441
by: AMDRIT | last post by:
Hello everyone, I have created a custom component and one of its properties is a class object with it's own properties. During runtime, I can assign values to the class object properties just fine. However, when attempting to assing default values as designtime in the propertygrid, nothing is working on the class object. I know that I am doing it wrong, any ideas what it is? Thanks in advance
0
3464
by: Pieter | last post by:
Hi, I'm using NHibernate 1.2 (CR1), and I'm using a custom list (inherited from BindingList(Of T) ) for all my lists. The NHibernate documentation told me that I had to implement IUserCollectionType to my custom list, which I did. But I still get an error when trying to read the object: " {"Unable to cast object of type 'NHibernate.Collection.Generic.PersistentGenericBag`1' to
0
8758
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9251
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9121
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
9017
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
7867
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6588
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
4432
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
3123
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2450
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.