#1658·imgui

Using BeginCombo() and avanced: custom preview, filtering

Author: ocornutCreated Mar 3, 2018Updated Sep 8, 2026
Labelstricks & tipspopupsuseful widgetsdoc

I feel like this is one of the small/nice feature that may have passed under the radar so I'm going to write a small blurb about it here.

There's a BeginCombo/EndCombo() api which is much more flexible that the "old" Combo() function.

bool BeginCombo(const char* label, const char* preview_value, ImGuiComboFlags flags = 0);
void EndCombo(); // only call EndCombo() if BeginCombo() returns true!

Basically with this api you can control the way you store your current selection and item storage (they don't have to be stored sequentially and randomly accessible, so if your natural "selection" data is a pointer you can use that, you can submit filtered lists easily, etc.

const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK", "LLLLLLL", "MMMM", "OOOOOOO", "PPPP", "QQQQQQQQQQ", "RRR", "SSSS" };
static const char* current_item = NULL;

if (ImGui::BeginCombo("##combo", current_item)) // The second parameter is the label previewed before opening the combo.
{
    for (int n = 0; n < IM_ARRAYSIZE(items); n++)
    {
        bool is_selected = (current_item == items[n]); // You can store your selection however you want, outside or inside your objects
        if (ImGui::Selectable(items[n], is_selected)
            current_item = items[n];
        if (is_selected)
            ImGui::SetItemDefaultFocus();   // You may set the initial focus when opening the combo (scrolling + for keyboard navigation support)
    }
    ImGui::EndCombo();
}

You can easily build combo boxes for your custom types using this.

Today I asked extra flags: ImGuiComboFlags_NoArrowButton

ImGuiComboFlags_NoPreview

You could previously achieve this by pushing an item width the width of the button only, but it's not doable with just a flag.

ImGuiComboFlags_NoPreview + hidden label:

Also consider creating custom layout like:

const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK", "LLLLLLL", "MMMM", "OOOOOOO", "PPPP", "QQQQQQQQQQ", "RRR", "SSSS" };
static const char* current_item = NULL;
ImGuiComboFlags flags = ImGuiComboFlags_NoArrowButton;

ImGuiStyle& style = ImGui::GetStyle();
float w = ImGui::CalcItemWidth();
float spacing = style.ItemInnerSpacing.x;
float button_sz = ImGui::GetFrameHeight();
ImGui::PushItemWidth(w - spacing * 2.0f - button_sz * 2.0f);
if (ImGui::BeginCombo("##custom combo", current_item, ImGuiComboFlags_NoArrowButton))
{
    for (int n = 0; n < IM_ARRAYSIZE(items); n++)
    {
        bool is_selected = (current_item == items[n]);
        if (ImGui::Selectable(items[n], is_selected))
            current_item = items[n];
        if (is_selected)
            ImGui::SetItemDefaultFocus();
    }
    ImGui::EndCombo();
}
ImGui::PopItemWidth();
ImGui::SameLine(0, spacing);
if (ImGui::ArrowButton("##r", ImGuiDir_Left))
{
}
ImGui::SameLine(0, spacing);
if (ImGui::ArrowButton("##r", ImGuiDir_Right))
{
}
ImGui::SameLine(0, style.ItemInnerSpacing.x);
ImGui::Text("Custom Combo");

Clicking the preview area will get you the normal combo popup, etc.