Как заставить ComboBox прокрутить вверх? - PullRequest
0 голосов
/ 08 июня 2018

У меня есть winforms ToolStripComboBox со свойством ComboBox.По умолчанию, кажется, автоматически прокрутить к выбранному индексу.Смотрите скриншот ниже:

enter image description here

При загрузке формы я устанавливаю SelectedIndex в 1, что и должно произойти.Но я хочу, чтобы первый элемент в списке (SelectedIndex 0) был виден, или, другими словами, автоматически прокручивался до самого верха.Я не могу найти способ заставить выпадающий список по умолчанию или сделать это программным путем.В ComboBox есть свойство AutoScrollOffset, с которым я экспериментировал, но оно, похоже, ничего не делает, независимо от того, что я его установил.

Как видно на моем скриншоте выше, я хочу вызвать комбинированный список (либо через свойство или вызов метода), чтобы появиться как 2-й рисунок, на котором виден верхний элемент ( Все - все категории ), при этом индекс 1 остается выбранным.

Как это может бытьсделано?

1 Ответ

0 голосов
/ 08 июня 2018

Когда вы открываете раскрывающийся список, в список, который находится в раскрывающемся меню, будет отправлено сообщение LB_SETTOPINDEX.Это сообщение отвечает за установку верхнего индекса в списке.

Вы можете обработать это сообщение и изменить его WParam на Intptr.Zero, чтобы всегда использовать 0 в качестве верхнего индекса.

Собственные методы

Вот класс, который содержит нативные методы, структуры и константы для управления комбинированным полем для этой цели:

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
public class NativeMethods
{
    [StructLayout(LayoutKind.Sequential)]
    public struct COMBOBOXINFO
    {
        public int cbSize;
        public RECT rcItem;
        public RECT rcButton;
        public int stateButton;
        public IntPtr hwndCombo;
        public IntPtr hwndEdit;
        public IntPtr hwndList;
    }
    [StructLayout(LayoutKind.Sequential)]
    public struct RECT
    {
        public int Left; public int Top; public int Right; public int Bottom;
    }
    [DllImport("user32.dll")]
    public static extern bool GetComboBoxInfo(IntPtr hWnd, ref COMBOBOXINFO pcbi);
    public class ListBoxHelper : NativeWindow
    {
        private const int LB_SETTOPINDEX = 0x0197;
        public ListBoxHelper(IntPtr hwnd) { this.AssignHandle(hwnd); }
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == LB_SETTOPINDEX)
                m.WParam = IntPtr.Zero;
            base.WndProc(ref m);
        }
    }
}

ComboBox

Вот ComboBox, раскрывающийся в раскрывающемся списке всегда с отображением элемента 0 в качестве верхнего элемента:

public class MyComboBox : ComboBox
{
    NativeMethods.ListBoxHelper listBoxHelper;
    protected override void OnHandleCreated(EventArgs e)
    {
        base.OnHandleCreated(e);
        var info = new NativeMethods.COMBOBOXINFO();
        info.cbSize = Marshal.SizeOf(info);
        NativeMethods.GetComboBoxInfo(this.Handle, ref info);
        listBoxHelper = new NativeMethods.ListBoxHelper(info.hwndList);
    }
}

ToolStripComboBox

ToolStripComboBoxхосты ComboBox внутри.Так что решение похоже:

public class MyToolStripComboBox : ToolStripComboBox
{
    public MyToolStripComboBox()
    {
        this.Control.HandleCreated += Control_HandleCreated;
    }
    NativeMethods.ListBoxHelper listBoxHelper;
    private void Control_HandleCreated(object sender, EventArgs e)
    {
        base.OnVisibleChanged(e);
        var info = new NativeMethods.COMBOBOXINFO();
        info.cbSize = Marshal.SizeOf(info);
        NativeMethods.GetComboBoxInfo(this.Control.Handle, ref info);
        listBoxHelper = new NativeMethods.ListBoxHelper(info.hwndList);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...