Click here to Skip to main content
Click here to Skip to main content

Multicolumn Combobox with Additional Format Conditions

, 9 May 2007 CPOL
Rate this:
Please Sign up or sign in to vote.
Multicolumn Combobox with additional format conditions depending on the displayed values
Screenshot - MCComboBox_pic.jpg

Introduction

It all began with a research for a dynamic multicolumn combobox. What I found had restrictions in the count of rows or fixed count of columns during the creation of the control. So I decided to develop a more flexible one.
Everything started with the multi column feature. Later on, I saw a wonderful feature during my development work at my job with the Janus GridEX control. It provided FormatConditions to define colors and font styles depending on field values, so I implemented my own variation of them.

Background

There are some specialities to take into account :

  • In addition to the format conditions, you can define a default format condition (type FCO_Default) that is used if no matching format condition could be found. For default format conditions, the Value1 pointer can be NULL.
  • The columns can be defined with a static width, or a dynamic width. The dynamic width is calculated by the function CalcDropdownListWidth(). So after changes or adding rows this function should be called.
  • Not all format condition operators make sense for every type of value (Between makes no sense with strings, Contains makes no sense with numeric values), so handle with care...

Using the Code

  • In your resource editor, create a combobox and set the owner draw property to Variable, the Include strings property to true and the dropdown type to DropDownList.
  • Use the classwizard to create a CComboBox object in your window.
  • Include the MCComboBox.h file in your class file.
  • Rename the CComboBox object type to CMCComboBox.
  • In the OnInitDialog() and OnInitialUpdate() you must define the columns. Format conditions and the row data can be added later in the code.

Here's the code snippet to produces the fantastic dropdown list you can see at the top of the article. The code creates a multicolumn combobox with 3 columns, 3 format conditions, one default format condition and 30 rows of data :

//    Adding the columns
this->m_cboMultiColumn.Add_Column( );
this->m_cboMultiColumn.Add_Column( );
this->m_cboMultiColumn.Add_Column( );

//    also use the format conditions in the edit control
this->m_cboMultiColumn.Set_ShowFormatConditionInEditField( true );

//    add the format conditions
//    red text and black background, if in column 0 the text "Row 3" appears
CFormatCondition    *pFormatCondition    = 
    this->m_cboMultiColumn.Create_FormatCondition( _T("TestCondition1"), 0, 
    CFormatCondition::FCO_Equal, new CMCCell( CString(_T("Row 3" ) ) ) );
if ( pFormatCondition != NULL )
{
    pFormatCondition->Set_Bold( true );
    pFormatCondition->Set_TextColor( RGB( 255, 0, 0 ) );
    pFormatCondition->Set_BackColor( RGB( 0, 0, 0 ) );
}

//    green text if in column 1 a date/time equal to 05.02.2007 12:00:00 appears
pFormatCondition    = this->m_cboMultiColumn.Create_FormatCondition
    ( _T("Date 1"), 1, CFormatCondition::FCO_Equal, 
    new CMCCell( COleDateTime(2007, 2, 5, 12,0,0 ), CMCCell::CT_Time ) );
if ( pFormatCondition != NULL )
{
    pFormatCondition->Set_TextColor( RGB( 0, 255, 0 ) );
}

//    blue text if in column 1 a date/time greater than 05.02.2007 12:00:00 appears
pFormatCondition    = this->m_cboMultiColumn.Create_FormatCondition
    ( _T("Date 2"), 2, CFormatCondition::FCO_GreaterThan, new CMCCell( (int)4 ) );
if ( pFormatCondition != NULL )
{
    pFormatCondition->Set_TextColor( RGB( 0, 0, 255 ) );
}

//    default format condition with golden text on dark red background, 
//    italic and striked out (uhhhhh.....)
pFormatCondition    = this->m_cboMultiColumn.Create_FormatCondition
    ( _T("Default"), 2, CFormatCondition::FCO_Default, new CMCCell( (int)0 ) );
if ( pFormatCondition != NULL )
{
    pFormatCondition->Set_TextColor( RGB( 255, 192, 64 ) );
    pFormatCondition->Set_BackColor( RGB( 128, 0, 0 ) );
    pFormatCondition->Set_Italic( true );
    pFormatCondition->Set_StrikeThru( true );
}

//    add 30 rows of data...
COleDateTime    dtDateTime( 2007, 2,5,10,0,0);
for ( int nIndex = 0; nIndex < 30; nIndex++ )
{
    CMCRow    *pRow    = new CMCRow( );
    if ( pRow )
    {
        pRow->Set_ItemData( (long)( nIndex + 1 ) );
            CString    strText;
        strText.Format( _T("Row %d"), nIndex, nIndex );
            pRow->Set_CellValue( 0, strText );
        pRow->Set_CellValue( 1, dtDateTime, CMCCell::CT_Time );
        pRow->Set_CellValue( 2, nIndex );
            this->m_cboMultiColumn.Add_Row( pRow );
    }
    dtDateTime    += COleDateTimeSpan( 0, 1, 0, 0 );
}
//    recalc the needed width for the dropdown list
this->m_cboMultiColumn.CalcDropdownListWidth( ); 

That's it. Have fun with it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Gismow
Web Developer
Germany Germany
No Biography provided

Comments and Discussions

 
QuestionHow SORT by first COLUMN ??? Pinmemberrodnarox17-Jul-08 0:23 
AnswerRe: How SORT by first COLUMN ??? Pinmemberrodnarox27-Aug-08 1:31 
I am apply simply sorting routine.
 
1. Define struct i *.h file:
 
typedef struct STRUCT_DEVICE_MAIN_TABLE
{
TCHAR dev_a[max_devices_count][max_device_length];
TCHAR dev_b[max_devices_count][max_device_length];
TCHAR dev_c[max_devices_count][max_device_length];
TCHAR dev_d[max_devices_count][max_device_length];
} DEVICE_LIST_MAIN_TABLE;
 

2. Add Bubble & Swap function to *.cpp file:
 
// sort the TCHARS array
void BubbleSort (TCHAR names[][max_device_length], int size)
{
int k = 0;
bool done = false;
int limit = 0;
TCHAR name[max_device_length]=_T("");
while (!done)
{
done = true;
for (int n=0; n<size-1-limit;>
 
// Your for loop is manipulating "n" not "k"
if (_tcscmp(names[n], names[n+1]) > 0)
{
// You wanted to pass names array, not name
Swap (names, n, n+1);
Swap (devlistMain.dev_b, n, n+1);
Swap (devlistMain.dev_c, n, n+1);
Swap (devlistMain.dev_d, n, n+1);
done = false;
}
limit++;
}
}
 
void Swap (TCHAR names[][max_device_length], int n, int k)
{
TCHAR temp[max_device_length];
_tcscpy_s(temp,max_device_length, names[n]);
_tcscpy_s(names[n], max_device_length, names[k]);
_tcscpy_s(names[k], max_device_length, temp);
}
 
3. Call bubble function
 
BubbleSort(devlistMain.dev_a, nCountOfDevices);
 

RodnaRox2008 Big Grin | :-D
GeneralThank YOU Pinmemberrodnarox16-Jul-08 23:57 
QuestionUsing MCComboBox Control With C# Pinmemberjasper01813-Jul-07 11:14 
AnswerRe: Using MCComboBox Control With C# PinmemberGismow15-Jul-07 21:10 
GeneralRe: Using MCComboBox Control With C# Pinmemberjasper01818-Jul-07 10:19 
GeneralSuggestion PinmvpHans Dietrich9-May-07 20:40 
AnswerRe: Suggestion PinmemberGismow9-May-07 21:29 
GeneralRe: Suggestion PinmvpHans Dietrich10-May-07 21:53 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.1411028.1 | Last Updated 9 May 2007
Article Copyright 2007 by Gismow
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid