65.9K
CodeProject 正在变化。 阅读更多。
Home

自定义分组组合框

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.80/5 (16投票s)

2001年6月13日

3分钟阅读

viewsIcon

213320

downloadIcon

3718

一个类似组合框的控件,允许下拉列表中的元素进行分组。

引言

在开发一个较大的应用程序时,我发现自己需要一个可以内部进行分组的CCombobox类型的控件。我希望该控件更像一个按钮装置,但带有一个用户可以选择的下拉列表...因此创建了 CDropButton 类。您可能之前在 Microsoft Money 中见过这种类型的控件。这是一种对下拉列表中的项目进行分组的绝佳方法。

该控件的功能非常强大,使用 CButton 类作为主类,以及 CWndCListbox 用于显示数据。它是完全可定制的,可以更改几乎所有内容的颜色,除了滚动条,这可能会在以后实现。

它的工作方式类似于普通的 CCombobox,只是项目分组在标题下。 标题以粗体和区分线显示。 标题本身是不可选择的,并且其数据是按字母顺序排列的。 CDropButton 可以设置为用选择替换按钮上的文本,或者不替换。

以下是默认控件的样子

以下是自定义控件的样子(漂亮吗?)

该控件非常易于使用

使用以下创建方法创建一个默认的 CDropButton

m_pDropBtn = new CDropButton();
m_pDropBtn->Create("Options", CRect(100,100,280,120), this, ID_DROP_BUTTON);

您还可以在创建中发送大量选项,以便根据您的喜好进行自定义!

COLORREF crButtonBackgroundColor = RGB(150,0,0);
COLORREF crButtonBackgroundOverColor = RGB(200,50,50);
COLORREF crButtonTxtColor = RGB(255,255,255);
COLORREF crButtonTxtOverColor = RGB(255,255,150);
CFont* pTextFont = NULL;

m_pDropBtn->Create("Options", CRect(300,100,450,120), this, ID_DROP_BUTTON,
                    crButtonBackgroundColor, crButtonBackgroundOverColor,
                    crButtonTxtColor, crButtonTxtOverColor, pTextFont);

// Set OPTIONAL parameters
m_pDropBtn->SetListHeight(200);    // Set the Width Height
m_pDropBtn->SetListWidth(170);    // Set the List Width
m_pDropBtn->ChangeTitleWithSelection(
  false);    // When the users selects an item change the title in the top

在上面的例子中,我没有设置字体,但这是可以的,默认为 14 磅的 Arial。'crButtonBackgroundOverColor' 参数使按钮在鼠标经过控件时改变颜色。

创建 CDropButton 后,您可以获取列表框并设置可选属性。

// Get the CListBox
CDropList* pList = m_pDropBtn->GetList();

// Set OPTIONAL paramters
pList->SetBkColor(crBkListColor);          // List background COlor
pList->SetHighlightBkColor(
  RGB(255,255,100));     // List highlight background color

然后添加数据。 第一组中的项目没有标题。 您可以使用标准的 CListBox AddString 函数来添加它们。

// Add default Items
pList->AddString("Split/Multiple Catagories...");
pList->AddString("Add New Category...");

您可以将特定项目添加到组。 您将组指定为第二个参数。 第三个和第四个参数是该特定项目的可选文本颜色。 每个项目都可以有特定的颜色!

// Add specific items with COLOR!!
pList->AddString("EXPENSE", 2, RGB(128,0,0), RGB(255,0,0));
pList->AddString("Automobile", 2);
pList->AddString("Health Care", 2);
pList->AddString("Gifts", 2);

pList->AddString("INCOME", 3, RGB(0,128,0), RGB(0,255,0));
pList->AddString("Wages/Salary", 3);
pList->AddString("Retirement Income", 3);
pList->AddString("Other Income", 3);

pList->AddString("SPECIAL", 4, RGB(0,0,128), RGB(0,0,255));
pList->AddString("Transfer", 4);
pList->AddString("Loan Payment", 4);
pList->AddString("Clothing", 2); // Out of order but OK!

该控件仅发回一条消息。 它向您发送一个 CM_SELECTION_CHANGED 消息,以告知您何时选择已更改。 要实现它,请将以下语句放在您的消息映射中

ON_MESSAGE(CM_SELECTION_CHANGED, OnSelectionChanged)

将此行放在您的头文件中

afx_msg LONG OnSelectionChanged(UINT wParam, LONG lParam);

处理此问题的函数看起来类似于这样

LONG CTestView::OnSelectionChanged(UINT wParam, LONG lParam)
{
    // What control sent the message
    CDropList* pList;
    switch(wParam)
    {
        case    ID_DROP_BUTTON:
                pList = m_pDropBtn->GetList();
                break;

        case    ID_DROP_BUTTON2:
                pList = m_pDropBtn2->GetList();
                break;
    }
    
    // Get the Current Selection and Display it
    CString csText;
    pList->GetText(pList->GetCurSel(), csText);
    AfxMessageBox(csText);

    return 1;
}
wParam 是发送消息的控件的 ID。

大多数标准的 CListBox 函数都可以工作,除了少数几个。 我没有测试过它是否适用于多重选择 CListBox! 在我的例子中,我不需要这个,因此没有尝试考虑它。 此外,InsertString 将不起作用,该控件会处理数据项的位置。

RemoveString 确实有效,但在删除标题项目时略有不同。 当删除标题项目时,其所有子项也会被删除。

大多数其他标准函数应该可以工作(SelectStringSetCurSel 等),但请注意我没有测试所有这些函数。 务必先尝试一下!

最后一件事,水平滚动不起作用! 我认为对于这个控件来说,这是不必要的。 但是,如果您确实需要它,只需将样式添加到 CDropList

CDropButton 背后的代码应该非常容易理解和修改。 如果您对代码进行更改(例如自定义滚动条),请发送给我一份副本! 我很乐意看到它!

这是在 Windows 2000 上使用 Visual C++ 6.0 创建的。

© . All rights reserved.