C# 如何强制组合框滚动到顶部?
我有一个带有ComboBox属性的winformsToolStripComboBox。默认情况下,它似乎自动滚动到所选索引。请参见下面的屏幕截图: 在表单加载时,我将SelectedIndex设置为1,这就是需要发生的事情。但我希望列表中的第一项(SelectedIndex 0)可见,或者换句话说,自动滚动到最顶端。我找不到任何方法来强制组合框在默认情况下滚动到顶部,或者以编程方式这样做。ComboBox上有一个C# 如何强制组合框滚动到顶部?,c#,.net,winforms,combobox,C#,.net,Winforms,Combobox,我有一个带有ComboBox属性的winformsToolStripComboBox。默认情况下,它似乎自动滚动到所选索引。请参见下面的屏幕截图: 在表单加载时,我将SelectedIndex设置为1,这就是需要发生的事情。但我希望列表中的第一项(SelectedIndex 0)可见,或者换句话说,自动滚动到最顶端。我找不到任何方法来强制组合框在默认情况下滚动到顶部,或者以编程方式这样做。ComboBox上有一个AutoScrolOffset属性,我已经尝试过了,但无论我将其设置为什么,它似乎
AutoScrolOffset
属性,我已经尝试过了,但无论我将其设置为什么,它似乎都不起作用
正如我上面的截图所示,我想强制组合框(通过属性或方法调用)显示为第二张图片,其中顶部项目(所有-所有类别)可见,同时仍保持索引1处于选中状态
如何做到这一点?打开下拉菜单时,将向下拉菜单中的列表发送一条消息。此消息负责设置列表中的顶部索引 您可以处理此消息并将其
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);
}
}
}
组合框
下面是一个组合框,它的下拉列表始终打开,显示项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);
}
}