Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Winforms: Add an "Select from list..." placeholder to databound combobox

I have a combobox which is databound like this:

comboBox.InvokeIfRequired(delegate
        {
            var data = db.GetData();
            comboBox.DisplayMember = "Value";
            comboBox.ValueMember = "ID";
            comboBox.DataSource = data;
        });

It works fine, but it preselects the first databound value. I want the combobox to be preselected with some placeholder like "Select item from list..."

What's the best way/approach to do that?
a) Adding to the data Variable empty item
b) Setting it through combobox variable properties? If so, which ones?
c) Other

like image 200
Adrian K. Avatar asked Sep 27 '22 18:09

Adrian K.


1 Answers

I found a solution for this here

The code for this is:

private const int EM_SETCUEBANNER = 0x1501;        

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern Int32 SendMessage(IntPtr hWnd, int msg, int wParam, [MarshalAs(UnmanagedType.LPWStr)] string lParam);

    [DllImport("user32.dll")]
    private static extern bool GetComboBoxInfo(IntPtr hwnd, ref COMBOBOXINFO pcbi);
    [StructLayout(LayoutKind.Sequential)]

    private struct COMBOBOXINFO
    {
        public int cbSize;
        public RECT rcItem;
        public RECT rcButton;
        public UInt32 stateButton;
        public IntPtr hwndCombo;
        public IntPtr hwndItem;
        public IntPtr hwndList;
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct RECT
    {
        public int left;
        public int top;
        public int right;
        public int bottom;
    }

    public static void SetCueText(Control control, string text)
    {
        if (control is ComboBox)
        {
            COMBOBOXINFO info = GetComboBoxInfo(control);
            SendMessage(info.hwndItem, EM_SETCUEBANNER, 0, text);
        }
        else
        {
            SendMessage(control.Handle, EM_SETCUEBANNER, 0, text);
        }
    }

    private static COMBOBOXINFO GetComboBoxInfo(Control control)
    {
        COMBOBOXINFO info = new COMBOBOXINFO();
        //a combobox is made up of three controls, a button, a list and textbox;
        //we want the textbox
        info.cbSize = Marshal.SizeOf(info);
        GetComboBoxInfo(control.Handle, ref info);
        return info;
    }

And then you can simple use it like this:

SetCueText(comboBox, "text");

This will also work for a textbox.

like image 105
Koen S Avatar answered Oct 03 '22 03:10

Koen S