Solved

Multiple ComboBoxes reference the exact same list.  Is there a better way?

Posted on 2003-12-01
13
293 Views
Last Modified: 2010-04-05
Hi,

I've got a question regarding the best approach to a problem.  I have an application that requires a selection box providing a list of items.  I need that same list of items in twenty other locations in the program.  Is there a better way than to populate those 20 comboboxes with the same stringlist derived from a table?  The problem also, is that each of these comboboxes need to retain the selection made.  If I use a dbcombo, the selection does not remain when another dbcombo makes a selection on the same table.  I've tried dblookupcomboboxes as well.   I also am concerned with the memory needed to have twenty comboboxes all with the same data to list.   Any suggestions are welcome and appreciated.

TD
0
Comment
Question by:tonydm
  • 3
  • 2
  • 2
  • +3
13 Comments
 
LVL 5

Accepted Solution

by:
DeerBear earned 25 total points
ID: 9849882
Hi,

Have a look at this:

uses Classes;

Type

   TSingleList = class
   private
       FList : TStringList;
   public
      constructor Create;
      destructor Destroy;override;

     property List : TStringList read FList;
   end;

function SingleList : TSingleList;

implementation

var _SingleList : TSingleList;

function SingleList : TSingleList;
begin
  if Not Assigned( _SingleList ) then
   _SingleList := TSingleList.Create;
  Result  := _SingleList;
end;

constructor TSingleList.Create;
begin
  Inherited Create;
  if Assigned( _SingleList ) then
     raise Exception.Create( 'Cannot create another instance' )
 else begin
          FList := TStringList.Create;
        end;
end;

destructor TSingleList.Destroy;
begin
  FList.Free;
  Inherited;
end;


Now, use the function SingleList to access the singleton application-wide!

HTH,

Andrew
0
 
LVL 3

Expert Comment

by:JDuncan
ID: 9850369
Are you actually re populating the boxes or are you doing the following :-

  Combobox2.Items:=Combobox1.Items;
  Listbox1.Items:=Combobox1.Items;
  AnyDelphiList.Items:=Combobox1.Items;
0
 
LVL 2

Expert Comment

by:Robn
ID: 9850588
tonydm,
No, not really. If you want to use the VCL, there is no way to solve your problem.
0
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 2

Expert Comment

by:classmate
ID: 9851052
actually there could be a lot of ways to solve this problem, but the best solution will depend on case specific details which are not given at this moment.

regards
classmate.

0
 
LVL 2

Expert Comment

by:Robn
ID: 9851194
If you're using the VCL, no there are not. However, you can easily create your own combo component with your own TStrings implementation that could be shared. You would need to manage the combo boxes so they can react to changes in the TStrings class. But this is easy to do.
If you're worried about memory resources, Delphi automatically does reference counting on strings. If you had the value "Hello World" in 20 combo boxes, Delphi would only allocate one string and share it out. The OS would still have 20 character arrays of "Hello World" though. This cannot be helped.
However, if you want something easier than managing 20 combo box items, you'll need to manage this yourself and create your custom component.
0
 
LVL 1

Expert Comment

by:roknjohn
ID: 9851793
tonydm,

Are you saying that you need 20 independent selections?  Or changing one changes all?  Is the users selection stored in the database? (in one field or twenty different fields?)

Your memory budget must be tight if you're worried about 20 short stringlists.  But if so, create them on-the-fly as needed, then free them afterwards.  Load a TStringsList with the items then assign it to the Items property of the combo:  ComboBox1.Items.Assign(MyStringList);
0
 

Author Comment

by:tonydm
ID: 9854736
wow!  thanks for all the rapid feedback.  Let me try and be a little more clear and answer as many ?'s as possible.  I'm new to Delphi, a novice, if you will.   My concern over memory is that my program is rather small, but has a compiled exe of a bit over 2mb.  That's will optimization, and no map or debug code.  My stringlist has about 300 1-3 digit strings.  So i was concerned about the impact that 20 comboboxes each containing the same information.  I am reading this information in from a table.  The selected item is then the key to seek on in the same table the list read for two other pieces of information.  This is then written to a temp file used will the app is running.  So in other words.  The user can select from multiple dropdowns, 20 of which provide the same information to pick from. I know, it sounds crazy, but it makes sense.  It is a kind of a schedule that the user is setting up over the course of a month.  There are a few other comboboxes with name, addr, etc.  matched with  I originally tried dbcomboboxes as well as blookupcomboboxes.  But in each case, whenever I would make a selection, the record pointer would change thereby reflecting in the other dbcomboboxes.  And something else that seemed strange to me was that I would still have to populate the dbcomboboxes with the same stringlist read from the table in which the dbcomboboxes were to derive there list.  I thought I had to missing some really simple.  But if I tried the same with a third party dbaware dbcombobox, I didn't have to populate that component with a stringlist.

The question was asked how I am populating the comboboxes.  The follow way:
Combobox1.Items.Assign(MyStringList);
Combobox2.Items.Assign(MyStringList), and so on...

And the dbcombo in the same manor.  The dblookupcombo provided the list without having to first populate the a strings property.  But as stated, move one db or dblookup and they all move.

I am using the vcl, in that I have populated number of tabsheets on a single form.  If this can be don't at runtime and then have at runtime that could be good.  If it really provides some benefit.

DeerBear, please, I'm looking at your code and with some study, I'm sure it will make sense, but could you explain in just a bit more detail?  Thank you, thank you.

TD
0
 
LVL 5

Expert Comment

by:DeerBear
ID: 9856224
Hi,

My code represents a singleton list, which holds a string list.
If you place that code in a unit( File|New...|Unit with D5+), you'll be able to
reference the EXACT SAME list from the whole application.

You can then assign them through the ComboBox1.AddStrings( SingleList.List ); and so on.
This will make you reference all the time from the same items.

HTH,

Andrew
0
 
LVL 2

Expert Comment

by:Robn
ID: 9858046
DeerBear's code will work perfectly for you if you were using 1 list for every combo box, but looking at your code sample....
Combobox1.Items.Assign(MyStringList);
Combobox2.Items.Assign(MyStringList), and so on...
it looks to me like you populate MyStringList with all the values and use this to populate the combo boxes which is essentially the same.

Unless you wanted to create a custom combo box that had the ability to share TStrings with other combo boxes (which to me seems like overkill) I would leave your code the way it is.

As I posted before, Delphi Strings are reference counted. Delphi has one of the most advanced String class I've seen in a development language.

There is nothing wrong with trying to tweek your code by writing the custom component, but you'll be spending a lot of time debugging it and I don't believe the gain will be worth the effort.

My $0.02

Regards,
Rob
0
 
LVL 1

Expert Comment

by:roknjohn
ID: 9858759
tonydm,

it sounds to me like you have a table of codes like this:

101  Wrench         2.50
102  Screwdriver   1.75
103  Hammer        3.50

And you want the user to select a code in 20 different places.  Then, you would probably be better off using 20 TDBLookupComboBox controls.  The trick here, though, is each one needs a different target DataField property.  This will keep each selection independent.  You will have to create a record in another table to hold the values.  (You mentioned earlier that this was a temporay file)  The DataSource should point to this new table.  The ListSource points to the table of codes, above.
0
 
LVL 3

Expert Comment

by:JDuncan
ID: 9866332

You could create and populate the combobox dyamically before the form is shown and destoy them when the form is closed. This way you would not be taking up any significant memory. The code to create / populate/ destroy the combobox could be held in a single unit you call.

0

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…

829 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question