如何强制ComboBox滚动到顶部?

时间:2018-06-07 22:44:00

标签: c# .net winforms combobox

我有一个带有ComboBox属性的winforms ToolStripComboBox 。默认情况下,它似乎自动滚动到所选索引。见下面的截图:

enter image description here

在表单加载时,我将SelectedIndex设置为1,这是需要发生的事情。但我希望列表中的第一项(SelectedIndex 0)可见,或者换句话说自动滚动到最顶层。我无法找到任何方法来强制组合框默认滚动到顶部,或者以编程方式执行此操作。 ComboBox上有一个AutoScrollOffset属性,我已经尝试过了,但无论我将它设置为什么,它似乎什么都不做。

如上面的截图所示,我想强制组合框(通过属性或方法调用)显示为第2张图片,其中顶部项目( All - 所有类别)可见,同时仍然选择索引1。

如何做到这一点?

1 个答案:

答案 0 :(得分:1)

当您打开下拉菜单时,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,其下拉列表始终打开,显示项目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);
    }
}