我有一个带有ComboBox属性的winforms ToolStripComboBox 。默认情况下,它似乎自动滚动到所选索引。见下面的截图:
在表单加载时,我将SelectedIndex设置为1,这是需要发生的事情。但我希望列表中的第一项(SelectedIndex 0)可见,或者换句话说自动滚动到最顶层。我无法找到任何方法来强制组合框默认滚动到顶部,或者以编程方式执行此操作。 ComboBox上有一个AutoScrollOffset
属性,我已经尝试过了,但无论我将它设置为什么,它似乎什么都不做。
如上面的截图所示,我想强制组合框(通过属性或方法调用)显示为第2张图片,其中顶部项目( All - 所有类别)可见,同时仍然选择索引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);
}
}