You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#中实现从数据库加载带分组标题的ComboBox

Grouped ComboBox with SQL Data Source

Got it, let's tackle this grouped ComboBox requirement. The standard WinForms ComboBox doesn't support native group headers, so we'll use owner-drawn items to achieve the exact layout you want—with section headers followed by paired data rows from your SQL database.

Step 1: Define a Data Model

First, create a class to represent both header and data items. This helps us distinguish between them when drawing and handling selections:

public class BioDataEntry
{
    // For header items, this holds the group name (e.g., "Neuropeptide")
    public string GroupName { get; set; }
    // For data items, these are your two SQL columns
    public string Identifier { get; set; }
    public string Label { get; set; }
    // Flag to mark if this is a header or data row
    public bool IsHeader { get; set; } = false;
}

Step 2: Fetch and Group Data from SQL

Next, pull your data from the database, group it by the data type, and populate a list with both headers and data rows:

List<BioDataEntry> comboItems = new List<BioDataEntry>();

// Replace with your actual connection string
string connectionString = @"Server=yourServer;Database=yourDB;Trusted_Connection=True;";

using (SqlConnection sqlConnection = new SqlConnection(connectionString))
{
    sqlConnection.Open();
    // Adjust the query to match your table/column names
    string query = @"SELECT DataType, Column1, Column2 
                     FROM YourBiologicalData 
                     ORDER BY DataType, Column1";
    
    using (SqlCommand cmd = new SqlCommand(query, sqlConnection))
    {
        using (SqlDataReader reader = cmd.ExecuteReader())
        {
            string currentGroup = null;
            
            while (reader.Read())
            {
                string groupName = reader["DataType"].ToString();
                
                // Add a header whenever we hit a new data type
                if (groupName != currentGroup)
                {
                    comboItems.Add(new BioDataEntry 
                    { 
                        GroupName = groupName, 
                        IsHeader = true 
                    });
                    currentGroup = groupName;
                }
                
                // Add the data row for this entry
                comboItems.Add(new BioDataEntry
                {
                    GroupName = groupName,
                    Identifier = reader["Column1"].ToString(),
                    Label = reader["Column2"].ToString(),
                    IsHeader = false
                });
            }
        }
    }
}

Step 3: Configure the ComboBox for Custom Drawing

Set up your ComboBox to use owner-drawn mode, then bind the populated list:

// In your form's constructor or load event
comboBoxBioData.DropDownStyle = ComboBoxStyle.DropDownList; // Prevent user input
comboBoxBioData.DrawMode = DrawMode.OwnerDrawFixed;
comboBoxBioData.ItemHeight = 22; // Adjust row height for readability
comboBoxBioData.DataSource = comboItems;

Step 4: Implement Custom Drawing

Handle the DrawItem event to render headers differently (bold, distinct color) and data rows as paired values:

private void comboBoxBioData_DrawItem(object sender, DrawItemEventArgs e)
{
    if (e.Index < 0) return;
    
    ComboBox combo = sender as ComboBox;
    BioDataEntry entry = combo.Items[e.Index] as BioDataEntry;
    
    // Draw the background
    e.DrawBackground();
    
    if (entry.IsHeader)
    {
        // Render header with bold font and dark color
        using (Font boldFont = new Font(combo.Font, FontStyle.Bold))
        {
            e.Graphics.DrawString(entry.GroupName, boldFont, Brushes.DarkSlateBlue, e.Bounds);
        }
    }
    else
    {
        // Render data row with combined columns
        string displayText = $"{entry.Identifier} {entry.Label}";
        e.Graphics.DrawString(displayText, combo.Font, Brushes.Black, e.Bounds);
    }
    
    // Draw the focus rectangle for selected items
    e.DrawFocusRectangle();
}

Step 5: Prevent Selecting Header Items

Add a SelectedIndexChanged handler to ensure users can't select header rows (auto-select the next data row instead):

private void comboBoxBioData_SelectedIndexChanged(object sender, EventArgs e)
{
    ComboBox combo = sender as ComboBox;
    if (combo.SelectedItem is BioDataEntry entry && entry.IsHeader)
    {
        // Move selection to the next data item if available
        if (combo.SelectedIndex + 1 < combo.Items.Count)
        {
            combo.SelectedIndex++;
        }
        else
        {
            combo.SelectedIndex = -1; // Clear selection if no data follows
        }
    }
}

This setup will give you exactly the grouped layout you described: bold section headers followed by your paired SQL data rows. Just adjust the query, column names, and styling (fonts/colors) to match your specific needs.

内容的提问来源于stack exchange,提问作者Christopher Ross

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:51:32