How make this code more generic?

W

Woody Splawn

From a Winform I am calling the sub routine that follows in a module

Public Sub PopulateWithStates(ByVal myform As Contracts, ByVal FieldName As
String)
Select Case FieldName
Case "txtST"
myform.txtST.Items.Clear()
myform.txtST.Items.Add("CA")
myform.txtST.Items.Add("WA")
End Select
End Sub

This works but what I would really like to do is not have to write a case
statement with all the states for each field that has a different name. I
did it this way only because I knew it would work but I would really like to
pass the name of the field involved by value in the Sub routine definition
but I don't know how. Something like

Public Sub PopulateWithStates(ByVal myform As Contracts, ByVal FieldName As
FieldObject)

MyForm.FieldObject.Items.clear()
myForm.FieldObject.Add("CA") etc.....

Could someone advise me on how to do this?
 
E

e

You've got it just about right I think, you just need a for each that cycles
through all your fields? Go with your second version of PopulateWithStates
you've got down there, and call it with something like this...?

Dim aFieldObject as FieldObject

For Each aFieldObject in <myForm.SomeObject.FieldsCollection>
PopulateWithStates(aFieldObject)
Next

....

Sub PopulateWithStates(byVal theFiledObject as FieldObject)

theFiledObject.Add("CA") etc.....

End Sub
 
J

Jay B. Harlow [MVP - Outlook]

Woody,
One question, do all fields get all states, or do different fields get
different sets of states. Assuming that all fields get all states:
Public Sub PopulateWithStates(ByVal myform As Contracts, ByVal FieldName As
FieldObject)
You're close.

How about passing in the list box or combo box itself (independent of the
form), this of course requires overloading (read duplication of code).
Public Sub PopulateWithStates(ByVal list As ComboBox)
Public Sub PopulateWithStates(ByVal list As ListBox)

Then you just pass in this listbox or combobox on the form.

PopulateWithStates(MyForm.lstStates)
PopulateWithStates(MyForm.cboStates)

Alternatively you could pass in the collection that the Items property
represents:
Public Sub PopulateWithStates(ByVal list As IList)

PopulateWithStates(MyForm.lstStates.Items)
PopulateWithStates(MyForm.cboStates.Items)

I like this last one as long as the control you are populating supports an
Items property that implements IList you can fill it with values.

Of course another even easier method is to have PopulateWithStates return a
"new" list of states, that you simply assign to the control's DataSource
property.

MyForm.lstStates.DataSource = PopulateWithStates()
MyForm.cboStates.DataSource = PopulateWithStates()

The reason I say it needs to be a "new" list (a new Array or new ArrayList
for example). A shared list will not work, as the binding process will
notice they are the same and keep both lists in sync. Cloning a shared array
would be good.

I prefer the last one, setting the DataSource property to the list I want
displayed.

Hope this helps
Jay
 
F

Fergus Cooney

Hiya Woody,

Public Sub PopulateWithStates _
(ByVal myform As Form1, ByVal sListBox As String)
Dim oControl As ListBox
Dim oListBox As ListBox
For Each oControl In myform.Controls
If oControl.Name = sListBox Then
oListBox = DirectCast (oControl, ListBox)
Exit For
End If
Next
If oListBox Is Nothing Then _
Return

oListBox.Items.Clear
oListBox.Items.AddRange (New String() _
{"CA", "WA", "FL"})
End Sub

Regards,
Fergus
 
W

Woody Splawn

Thank your for responding.

I think we are mis-communicating. I call this function with a statment
inside my form like this:

Module1.PopulateWithStates(Me, "txtST")

I am passing the name of the field that I want to populate to the
subroutine.

I'm hoping to write something like the following in the actual subroutine:

Public Sub PopulateWithStatesB(ByVal myform As Contracts, ByVal FieldName As
Object)
myform.FieldName.Items.Clear()
myform.FieldName.Items.Add("-")
myform.txtST.Items.Add("CA")
myform.txtST.Items.Add("WA")
myform.txtST.Items.Add("AZ")
... other 52 states
End Sub

I would like, if possible, for the subroutine to understand that when I say
FieldName I mean the text field on myForm called txtST. The reason I am
doing things this way is because I have several different fields on the form
that need to be populated with states but I would like to write the code for
adding states only once. When I use the code above I get a squiqqly under
MyForm.FieldName stating that FieldName is not a member of the form called
(in this case) contracts.

Am I making since?
 
J

Jay B. Harlow [MVP - Outlook]

Woody,
I am passing the name of the field that I want to populate to the
subroutine.
As my other post suggested, why pass the name of the field, when you can
pass the control itself?
Am I making since?
Yes, you are making sense.

Hope this helps
Jay
 
E

e

I'm a little foggy on what type of control we're talking about here, but the
premise should be the same no matter what the control type is, so I guess it
doesn't matter - is there a specific reason you have to pass the object name
as a literal string? If you just pass the control object itself, you should
be good to go. You don't have to use a for-each; if it's just for a few
specific ones, you can just send them by hand:

Module1.PopulateAnObjectWithStates(txtSt)
Module1.PopulateAnObjectWithStates(txtSomethingElse)
..... other ones you want to populate with states just like that

....

Public Sub PopulateAnObjectWithStates(ByVal obj As System.Object)
obj.Items.Clear()
obj.Items.Add("-")
obj.Items.Add("CA")
obj.Items.Add("WA")
obj.Items.Add("AZ")
... other 52 states
End Sub


I don't think passing the form would be necessary, it will change the object
directly.
 
C

Cor

Hi Fergus,

I see always examples form you telling how to use a collection class.
And now we have to my idea the standard example for it and you come with
this, I am perplex.

This is the basic example I thougth from that collection class.
properties
"CA", "Calfornia", "Timezone" or whatever
"WA", "Wasington", ................
"FL", "Florida", ......................

Or am I wrong

That you can just bind to the controls or whatever way you want to use it.

This was your answer
\\\
oListBox.Items.AddRange (New String() _
{"CA", "WA", "FL"})
End Sub
///

I say of course nothing, because two reasons, I get the idea I never
understand Woody and this I called your stuff and I don't want to make you
laughing to much about me.
:)
Cor
 
P

Peter Huang [MSFT]

Hi Woody,

It seems you want to addressing WinForm Controls by Name.
You need to maintain a HashTable for the relationship between the index and
the name.
So that you can get the index from its name, and then by using the
form.controls(index) to access the control.

http://groups.google.com/groups?q=FindControl+winform&hl=zh-CN&lr=&ie=UTF-8&
oe=UTF-8&selm=u72StMXiBHA.1552%40tkmsftngp02&rnum=1


Regards,
Peter Huang
Microsoft Online Partner Support
Get Secure! www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

--------------------
 
F

Fergus Cooney

Hi Cor,

No worries, mate - it's a case of 'horses for courses'. ;-)

In this situation Woody just wants to stick some strings into a ListBox -
so there's no need for anything more than an array of strings. If there <had
been> associated items, then, yes, I would have added objects, as in the other
similar queries.

[Can't understand why Woody hasn't seen the code, though.]

Regards,
Fergus
 
C

Chris Dunaway

Hiya Woody,

Public Sub PopulateWithStates _
(ByVal myform As Form1, ByVal sListBox As String)
Dim oControl As ListBox
Dim oListBox As ListBox
For Each oControl In myform.Controls
If oControl.Name = sListBox Then
oListBox = DirectCast (oControl, ListBox)
Exit For
End If
Next
If oListBox Is Nothing Then _
Return

oListBox.Items.Clear
oListBox.Items.AddRange (New String() _
{"CA", "WA", "FL"})
End Sub

Regards,
Fergus

Shouldn't the second line be:

Dim oControl As Control '????

The For Each will puke on any control that's not a ListBox

Chris
 
F

Fergus Cooney

Hi Chris,

ROFL, uurgh puke all over my For Each loop.

Doh! Yes, of course, it should be Control.

I tested it on a Form containing nothing but listboxes. No puke there -
but only because I was feeding it vanilla icecream rather than 10 pints of
lager and five straight whiskies followed by chicken vindaloo and a double
kebab.

Regards,
Fergus
 
W

Woody Splawn

Thank you. This worked for me.

Public Sub PopulateWithStates(ByVal FieldName As System.Object)
FieldName.items.Clear()
FieldName.Items.Add("CA") etc....


This was simple and straight forward and something I understand. Some of
the other solutions were frankly over my head but thank you to those that
responded.

Woody
 
P

Peter Huang [MSFT]

Hi Woody,

Did my suggestion works for you?
If you have any related question, please feel free to let me know.

Regards,
Peter Huang
Microsoft Online Partner Support
Get Secure! www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
--------------------
X-Tomcat-ID: 218518442
References: <[email protected]>
MIME-Version: 1.0
Content-Type: text/plain
Content-Transfer-Encoding: 7bit
From: (e-mail address removed) (Peter Huang [MSFT])
Organization: Microsoft
Date: Tue, 14 Oct 2003 08:57:29 GMT
Subject: Re: How make this code more generic?
X-Tomcat-NG: microsoft.public.dotnet.languages.vb
Message-ID: <[email protected]>
Newsgroups: microsoft.public.dotnet.languages.vb
Lines: 114
Path: cpmsftngxa06.phx.gbl
Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.languages.vb:146484
NNTP-Posting-Host: TOMCATIMPORT1 10.201.218.122

Hi Woody,

It seems you want to addressing WinForm Controls by Name.
You need to maintain a HashTable for the relationship between the index and
the name.
So that you can get the index from its name, and then by using the
form.controls(index) to access the control.

http://groups.google.com/groups?q=FindControl+winform&hl=zh-CN&lr=&ie=UTF-8 &
oe=UTF-8&selm=u72StMXiBHA.1552%40tkmsftngp02&rnum=1


Regards,
Peter Huang
Microsoft Online Partner Support
Get Secure! www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

--------------------
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top