Introduction
I have got a requirement to show a huge dataset of about 5000 records from an MSAccess database in a combobox. Additionally it needed to have few copies of the same combobox in the same dialog. Even though the time taken for data retrieval was less, the time to add all the 5000 records to 4 to 5 comboboxes with sort style took up a substantial amount of time and had become a bottle neck.
Since the data used in all the comboboxes was the same and the data retrieved was in the sorted order, I did not want to repilicate the data in all comboboxes while running on sort loop. So I came up with the interface IComboBox
which is used to display the data by all the comboboxes. The implemented interface can serve the data from anywhere at runtime, like from db etc. Do not do any direct data additions and deletions to the combobox using CComboBox
pointers. Use the CComboBoxDataBind
class, which in turn delegates all the calls to IComboBox
interface.
For example, if you are using a string Array or 10000 records, the addition, deletion and updation are be done through the string Array and must accordingly serve the data at runtime through the IComboBox
interface using the string Array. This works absolutely well for a dataset of about 50000 records with out much intial overhead of startup time.
One useful feature is, the resizing drop list. The top right corner and bottom right corner 5 square pixels on the scroll bar are sensible areas which can be used to resize the droplist. Not very user friendly in indicating the feature but is functional.
Suggested senarios where it would be useful
Before you decide to use this combobox you need to ask few questions
How huge is your dataset?
I suggest to use this with huge datasets only.
How is your data set changing at runtime, i.e, insert/update/delete?
If the data set is changing dynamically from front end and if it required resorting, I would suggest to go for default windows combobox. Otherwise you need stress more with data modifications functions AddString
, InsertString
, DeleteString
.
Is your data modification synchronous or asynchronous?
CComboBoxDataBind
is a very good choice if your data is changing asynchronously at the backend. For example, a column in the data base. You dosen't need to worry much about data modifications and you can directly plug into the database and serve the interface dynamically.
Is your data sorted? And would you want combobox to sort the data?
Sorting is not supported. If you need combobox to sort the data I suggest to use the default windows combobox.
Do you have multiple copies of same combobox in your GUI?
If you have multiple copies of same combobox, this is a right choice. Just use and use and use the same data object for all the combos.
Demo
The demo project demostrates how to use CComboBoxDataBind
with three different styles. First one uses the default functionality, second one is set to pop up on focus and third is used as always pop on child. A single dataset is used for all the combos.
When you run the application make sure you got the wordlist.txt present in the current working directory. wordlist.txt contains a sorted list of english dictionary words, about 70000 of them. The first line in the wordlist.txt contains the number of words in the file.
ComboData.h and ComboData.cpp implements the interface. Data addition, insertion and deletion are not implemented for the demo. CComboBoxDataBind
is tested with the droplist
style. Would also work fine with dropdown
style but not throughly tested.
Using the Control
The data binding happen through the interface
IComboBox.
The following are the functions needed to be implemented:
virtual int GetCount()=0;
virtual CString GetString(int index)=0;
virtual DWORD GetItemData(int index)=0;
virtual void* GetItemDataPtr(int index)=0;
virtual BOOL IsSorted()=0;
virtual int AddString( LPCTSTR lpszString )=0;
virtual int DeleteString( UINT nIndex )=0;
virtual int InsertString( int nIndex, LPCTSTR lpszString )=0;
Bind the MFC wizard created
CComboBox
controls using DDX to the
CComboBoxDataBind
variable.
CComboBoxDataBind m_ComboBoxDataBind1;
DDX_Control(pDX, IDC_COMBO1, m_ComboBoxDataBind1);
Bind the implemented IComboBox
data interface to the CComboBoxDataBind
variable.
m_ComboBoxDataBind1.SetIComboBox(&m_ComboData);