Pass different controls as parameter

I have a method that I want to use to read text files into either a ListBox or a TextArea. I want to pass the name of the ListBox or TextArea and the name of the text file as parameters. First, what type is required by parameter cntlType? Second, what kind of checking in an If Then or Select Case structure would determine the type of cntlType to execute the proper line of code to read into the ListBox or TextArea? Thanks!

LoadBox(cntlType as ??? , fileName As String)
Dim f As FolderItem
Dim stream As TextInputStream
f = GetFolderItem(fileName)
stream = TextInputStream.Open(f)
(Control Logic Here)
cntlType.addrow stream.readline //Read line into ListBox, repeat until EOF

cntlType.text = stream.readall //Read all into ListArea

you probably won’t be able to do that since, while both ultimately inherit from RectControl, their ancestors are quite different (and the text handling ability of each is in those different ancestors)

Your best best would be 3 methods … with one being private
1st one is for Listboxes
2nd for TextArea
3rd actually gets and returns the data…

and I THINK for Listbox you can just say LB.cell(-1)=theString

SUB loadListbox(lb as listbox,filename as string)
dim s as string = loadString(filename)
lb.cell(-1)=s
END SUB
SUB loadTextarea(ta as textarea,filename as string)
dim s as string = loadString(filename)
ta.text=s
END SUB
PRIVATE FUNCTION loadString(filename as string) as string
Dim f As FolderItem 
Dim stream As TextInputStream 
f = GetFolderItem(fileName)
stream = TextInputStream.Open(f)
return stream
END FUNCTION

Thanks Dave. I appreciate your time to respond. I was starting to think it could not be done the way I wanted it to work. But I’m a nooby and thought I would ask.

A better approach, IMHO, is to subclass the listbox and make your load method a method of the subclass. Then you just refer to the LB as me. (i.e. me.addrow “whatever”)

Sounds like a good use for interfaces
You could create an interface eg. DataLoader with a method LoadData(data as text). Subclass whatever controls can accept the data and add the interface to the subclasses. Then the LoadBox Method would accept a DataLoader as the argument and send the data to the LoadData method of whatever object it was given. Then the listbox,textarea or whatever class you like can know what to do with the data. No if then / select case required. In fact you probable don’t even need the LoadBox method. Just load the data directly to the object’s interface implementation.

Thanks Roger and Jim.

A slight variant of Dave’s idea is to put the 3 methods in a Module and make the 2 public ones extensions. This allows you to write…

myListbox.loadFileData("myFilePath") myTextArea.loadFileData("myFilePath")

The signatures then would look like this (just an extra “extension” keyword).

SUB loadFileData(extension lb as listbox, filename as string) SUB loadFileData(extension ta as TextArea, filename as string) PRIVATE FUNCTION loadString(filename as string) as string

Definitely a job for an interface.

I finally figured out how to pass controls as parameters. While maybe not the most efficient it is at least possible. This method is passed either a TextArea or a ListBox as a parameter. The method then determines if the parameter is a ListBox or a TextArea and then adds text to the appropriate control. The keys points are (1) parameter type is Auto (2) Must assign the parameter to an appropriate (ListBox or TextArea is this case) variable to use.

Sub TestMethod(Cntl as Auto)
If Cntl IsA TextArea Then
Dim ta As New TextArea
ta = Cntl
ta.Text = “Text for a text area”
ElseIf Cntl IsA ListBox Then
Dim lb As New ListBox
lb = Cntl
lb.AddRow(“Text for a list box”)
Else
// Error Handling
End If

Phillip,

I like how you use Auto… In Web Apps, you could have made your param be a WebControl, but using Auto is even easier!

So cool how there are so many ways to accomplish the same thing.

In a procedural world often “functions” had to know a lot about the innards of the things they were manipulating.

But in an OO world they should not
Hence why I’d say that the method Philip settled on is the least OO
The extension methods is better since each method will only extend a specific type and makes it appear like that type then has a new method to add text / data - however this relies on a convention for the name rather than a required interface (ie/ if you have a typo in one extends for a type then that type you want to use will just not compile for a reason that may not be immediately apparent)
Two subclasses that implement an common interface would be, IMHO, best
And you pass in a instance of the INTERFACE type

ie/

   Interface iTextAdder
             sub AddText( s as string )
   End Interface

   Class MyCustomTextArea
       inherits TextArea
       implements iTextAdder
             sub AddText( s as string )
                  self.appendText s
             end sub
   End Class

   Class MyCustomListBox
       inherits ListBox
       implements iTextAdder
             sub AddText( s as string )
                  self.addRow s
             end sub
   End Class

Then Phillips method turns into

// note you pass an instance that implements the interface for type safety
Sub TestMethod(Cntl as iTextAdder) 
         cntl.AddText "this is text for whatever I got passed"
End Sub

If you want to narrow down the possible Contl parameter types, as Auto could be anything, you can of course use Contl as RectControl, the latter being the base class of controls. If you would use only TextAreas and Textfields, you could use a parameter of type TextEdit.

great discussion!!