我在 UI 中有几个组合框,每个组合框都有一长串相似的条目(数字)。当用户从一个组合框中选择一个项目时,我知道用户会从其他组合框中选择一个具有相似值(但可能不相同)的条目。因此,在用户选择了一个值后,为了帮助避免强迫用户进行大量滚动,我想“自动滚动”下一个组合框下拉菜单到最后一个选定值附近(当这个下拉菜单还没有一个选择)。理想情况下,我希望设置滚动位置,以便最后选择的值出现在下拉列表的中间。
到目前为止,我已尝试通过在下拉事件中设置所选项目来做到这一点,但这有其自身的问题。有没有办法设置下拉的滚动位置而不必选择一个项目?
到目前为止,我已经尝试过:
[DllImport("user32.dll", EntryPoint = "SendMessageW", CharSet = CharSet.Unicode)]
private static extern IntPtr SendMessageCb(IntPtr hWnd, int msg, IntPtr wp, out COMBOBOXINFO lp);
[DllImport("user32.dll")]
private static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam);
// P/Invoke declarations
private struct COMBOBOXINFO
{
public Int32 cbSize;
public RECT rcItem, rcButton;
public int buttonState;
public IntPtr hwndCombo, hwndEdit, hwndList;
}
private struct RECT
{
public int Left, Top, Right, Bottom;
}
private const int LVM_FIRST = 0x1000;
private const int LVM_SCROLL = (LVM_FIRST + 20);
private const int WM_VSCROLL = 0x0115;
private const int SB_BOTTOM = 7;
private const int SB_PAGEDOWN = 3;
private void comboBox_DropDown(object sender, EventArgs e)
{
COMBOBOXINFO info = new COMBOBOXINFO();
info.cbSize = Marshal.SizeOf(info);
SendMessageCb((sender as ComboBox).Handle, 0x164, IntPtr.Zero, out info); // seems to work
SendMessage(info.hwndList, WM_VSCROLL, (IntPtr)SB_PAGEDOWN, IntPtr.Zero); // does nothing
SendMessage(info.hwndList, LVM_SCROLL, IntPtr.Zero, (IntPtr) 50); // does nothing
}
但是,这似乎不起作用。COMBOBOXINFO 结构似乎已正确填充,但 SendMessage WM_VSCROLL 和 LVM_SCROLL 无效。