【问题标题】:How to force ComboBox to scroll to top?如何强制 ComboBox 滚动到顶部?
【发布时间】:2018-06-07 22:44:00
【问题描述】:

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

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

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

如何做到这一点?

【问题讨论】:

    标签: c# .net winforms combobox


    【解决方案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);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-09
      • 1970-01-01
      • 2016-05-27
      • 2015-03-25
      • 2010-11-06
      • 2010-11-17
      相关资源
      最近更新 更多