Recent

Author Topic: Two column ComboBox.  (Read 19642 times)

chrnobel

  • Sr. Member
  • ****
  • Posts: 283
Two column ComboBox.
« on: April 24, 2013, 12:23:15 am »
In an application, I am going to populate a ComboBox with some unique values for reference, but I would like to have another column, which is the one the user sees, where there is some more descriptive text.

So how do I make a ComboBox multi column?

Regards
Christian

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Two column ComboBox.
« Reply #1 on: April 24, 2013, 12:32:47 am »
use a lookupcombo
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

chrnobel

  • Sr. Member
  • ****
  • Posts: 283
Re: Two column ComboBox.
« Reply #2 on: April 24, 2013, 10:00:43 am »
use a lookupcombo
As I can see there is only a database aware lookupcombo (TDbLookpComboBox), not a non db related one.

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Two column ComboBox.
« Reply #3 on: April 24, 2013, 10:12:14 am »
true that is because a simple combo box does not support more than 1 fields by design. In order to make it support more you need a mechanism to distinguish between the fields and the existing mechanism that does that is a dataset. Depending on your use case it might be an over kill. In any case the default behavior is what you have observed so far, for any thing else you have to write your own controls.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

chrnobel

  • Sr. Member
  • ****
  • Posts: 283
Re: Two column ComboBox.
« Reply #4 on: April 24, 2013, 11:07:59 am »
true that is because a simple combo box does not support more than 1 fields by design. In order to make it support more you need a mechanism to distinguish between the fields and the existing mechanism that does that is a dataset. Depending on your use case it might be an over kill. In any case the default behavior is what you have observed so far, for any thing else you have to write your own controls.
It is possible in MSEGUI, but unfortunately MSEGUI has some caveats that have stopped me in using it - OT I would love to see some of the strong grids and controls in MSE implemented in Lazarus.

I see no reason to reinvent the wheel, as I would guess some one else also have faced the same problem, and I do definitely not consider the issue as overkill.

I have found the following D7 code:

http://stackoverflow.com/questions/16006577/how-to-create-a-combobox-with-two-columns-in-delphi-7

but it is not possible for me to retrieve the value in this line:

Value := ComboBox1.Objects[Idx];

as it apparently is done differently in FreePascal.

BigChimp

  • Hero Member
  • *****
  • Posts: 5740
  • Add to the wiki - it's free ;)
    • FPCUp, PaperTiger scanning and other open source projects
Re: Two column ComboBox.
« Reply #5 on: April 24, 2013, 11:16:44 am »
Don't know if the rx components from the laz ccr repo  (see wiki page) contain extended versions... you might have a look there.
Want quicker answers to your questions? Read http://wiki.lazarus.freepascal.org/Lazarus_Faq#What_is_the_correct_way_to_ask_questions_in_the_forum.3F

Open source including papertiger OCR/PDF scanning:
https://bitbucket.org/reiniero

Lazarus trunk+FPC trunk x86, Windows x64 unless otherwise specified

JD

  • Hero Member
  • *****
  • Posts: 1916
Re: Two column ComboBox.
« Reply #6 on: April 24, 2013, 11:24:25 am »
@chrnobel
I have a client server application that is built around this functionality and it works perfectly. The combobox has a hidden ID column and a text column. The user only sees the text column. The hidden ID column is used for database lookups.

Here's how I populate a combobox from a TCollection that has an ID and a text field.

Code: [Select]
      // Fill the combobox from the TCollection
      AComboBox.Items.BeginUpdate;
      AComboBox.Clear;
      for intCount := 0 to ACollection.Count - 1 do
        // Add the string as well as its "hidden" ID to the combobox
        AComboBox.Items.AddObject(Trim(ACollection[intCount].Text), TObject(ACollection[intCount].Integer));
      AComboBox.Items.EndUpdate;

To retrieve the hidden ID value corresponding to a user's text selection, you do the following:

Code: [Select]
intID := Integer(AComboBox.Items.Objects[AComboBox.ItemIndex]);

You can easily replace the TCollection with a Dataset, StringList etc as you please. Note that this is an ordinary combobox i.e the default Lazarus combobox so you don't have to install anything.

I hope you find it useful.

JD
« Last Edit: April 24, 2013, 11:37:56 am by JD »
Linux Mint - Lazarus 4.8/FPC 3.2.2,
Windows - Lazarus 4.8/FPC 3.2.2

mORMot 2, PostgreSQL & MariaDB.

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Two column ComboBox.
« Reply #7 on: April 24, 2013, 11:50:09 am »
It is possible in MSEGUI, but unfortunately MSEGUI has some caveats that have stopped me in using it - OT I would love to see some of the strong grids and controls in MSE implemented in Lazarus.

I see no reason to reinvent the wheel, as I would guess some one else also have faced the same problem, and I do definitely not consider the issue as overkill.

I have found the following D7 code:

http://stackoverflow.com/questions/16006577/how-to-create-a-combobox-with-two-columns-in-delphi-7

but it is not possible for me to retrieve the value in this line:

Value := ComboBox1.Objects[Idx];

as it apparently is done differently in FreePascal.

You do understand that you are using a short cut aka a hack here write? the problem with such a hack is that it requires constant attention when working with it.
Having said that to solve the problem on the line you mention you need to typecast the result to an integer. this of course will work only on 32bit operating systems and will probably create a lot of problems on 64bit systems.

Code: [Select]
Value := Integer(ComboBox1.Objects[Idx]);

you can always put the directive {$MODE DELPHI} on top of the unit where you require delphi compatibility as well.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

chrnobel

  • Sr. Member
  • ****
  • Posts: 283
Re: Two column ComboBox.
« Reply #8 on: April 24, 2013, 11:54:19 am »
Code: [Select]
intID := Integer(AComboBox.Items.Objects[AComboBox.ItemIndex]);
Perfect thanks JD, this line did the trick (showing the difference to D7).

/Christian

chrnobel

  • Sr. Member
  • ****
  • Posts: 283
Re: Two column ComboBox.
« Reply #9 on: April 24, 2013, 11:59:29 am »
You do understand that you are using a short cut aka a hack here write? the problem with such a hack is that it requires constant attention when working with it.
Ehh sorry, but I don't get the point???
Quote
Having said that to solve the problem on the line you mention you need to typecast the result to an integer. this of course will work only on 32bit operating systems and will probably create a lot of problems on 64bit systems.
Why?

/Christian

JD

  • Hero Member
  • *****
  • Posts: 1916
Re: Two column ComboBox.
« Reply #10 on: April 24, 2013, 12:30:29 pm »
Code: [Select]
intID := Integer(AComboBox.Items.Objects[AComboBox.ItemIndex]);
Perfect thanks JD, this line did the trick (showing the difference to D7).

/Christian

You're welcome.
Linux Mint - Lazarus 4.8/FPC 3.2.2,
Windows - Lazarus 4.8/FPC 3.2.2

mORMot 2, PostgreSQL & MariaDB.

wp

  • Hero Member
  • *****
  • Posts: 13646
Re: Two column ComboBox.
« Reply #11 on: April 24, 2013, 02:02:04 pm »
To be compatible with 64 bit, type-cast to PtrInt instead of integer.

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Two column ComboBox.
« Reply #12 on: April 24, 2013, 02:26:38 pm »
You do understand that you are using a short cut aka a hack here write? the problem with such a hack is that it requires constant attention when working with it.
Ehh sorry, but I don't get the point???

You are using a tobject container as a numeric container this needs attention all the time that it returns the correct results for example on 64bit systems the tobject container has a size of 8 bytes while you are requesting 4 bytes depending on the memory model (big endian or small) it might always return 0 or the correct number or something else. In order to make sure that it will work as expected on all the circumstances you could use a pointer based type e.g. PInteger. This way you are completely sure that the tobject container and your variable are a 100% much under all circumstances.

this type of coding is some what ok in the private section of a class but it should never appear in the end user code it makes testing and porting a lot easier to eg port TMyCustomComboBox which uses the above technick to support multiple fields from hunting down a number of files/forms that use it.

the ideal solution is to have a combo box that can support multiple fields by design using a collection or something internally instead of a stringlist.


Quote
Having said that to solve the problem on the line you mention you need to typecast the result to an integer. this of course will work only on 32bit operating systems and will probably create a lot of problems on 64bit systems.
Why?

/Christian

see above
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

 

TinyPortal © 2005-2018