Как заставить ComboBox стиля DropDownList открываться только тогда, когда пользователь нажимает кнопку раскрывающегося списка? - PullRequest
5 голосов
/ 25 июня 2009

В C # .NET 2.0 у меня есть WinForms ComboBox с ComboBoxStyle DropDownList. Однако раскрывающийся список появляется всякий раз, когда пользователь щелкает в любом месте поля со списком. Вместо этого я хотел бы, чтобы он открывался только тогда, когда пользователь явно нажимает кнопку раскрывающегося списка. Когда пользователь нажимает на оставшуюся часть поля со списком, я хотел бы просто назначить ему фокус клавиатуры, чтобы он мог использовать некоторые команды клавиатуры для выбранного элемента. Какой лучший способ сделать это?

Ответы [ 3 ]

4 голосов
/ 25 июня 2009

После некоторой помощи от других ответов я пришел к этому быстрому решению:

public class MyComboBox : ComboBox
{
    public MyComboBox()
    {
        FlatStyle = FlatStyle.Popup;
        DropDownStyle = ComboBoxStyle.DropDownList;
    }

    protected override void WndProc(ref Message m)
    {
        if (m.Msg == 0x0201 /* WM_LBUTTONDOWN */ || m.Msg == 0x0203 /* WM_LBUTTONDBLCLK */)
        {
            int x = m.LParam.ToInt32() & 0xFFFF;
            if (x >= Width - SystemInformation.VerticalScrollBarWidth)
                base.WndProc(ref m);
            else
            {
                Focus();
                Invalidate();
            }
        }
        else
            base.WndProc(ref m);
    }
}
1 голос
/ 25 июня 2009

У вас есть две проблемы для рассмотрения. Первый довольно прост: определите, должен ли раскрывающийся список быть открыт или закрыт. Этот код может сделать это:

    void comboBox1_MouseClick(object sender, MouseEventArgs e)
    {
        ComboBox combo = sender as ComboBox;
        int left = combo.Width - (SystemInformation.HorizontalScrollBarThumbWidth + SystemInformation.HorizontalResizeBorderThickness);
        if (e.X >= left)
        {
            // They did click the button, so let it happen.
        }
        else
        {
            // They didn't click the button, so prevent the dropdown.
        }
    }

Вторая проблема более важна - фактически предотвращение появления выпадающего меню. Самый простой подход:

comboBox1.DropDownStyle = ComboBoxStyle.DropDown;

Но это позволяет вводить текст в поле, которое вам может не понадобиться.

Я потратил около 15 минут на просмотр параметров, и, похоже, чтобы предотвратить появление раскрывающегося списка и одновременно запретить пользователю вводить раскрывающийся список, необходимо создать подкласс управления. Таким образом, вы можете переопределить OnMouseClick () и вызывать base.OnMouseClick () только тогда, когда они нажимают кнопку. Это будет выглядеть примерно так (не проверено):

public class CustomComboBox : ComboBox
{
    protected override void OnMouseClick(MouseEventArgs e)
    {
        base.OnMouseClick(e);

        int left = this.Width - (SystemInformation.HorizontalScrollBarThumbWidth + SystemInformation.HorizontalResizeBorderThickness);
        if (e.X >= left)
        {
            // They did click the button, so let it happen.
            base.OnMouseClick(e);
        }
        else
        {
            // They didn't click the button, so prevent the dropdown.
            // Just do nothing.
        }
    }
}
0 голосов
/ 25 июня 2009

Вы можете получить положение X, Y щелчка мыши, и оттуда вы можете заставить его свернуться, если его нет на выпадающем «значке» (из-за отсутствия лучшего слова).

...