我有一个UI几个组合框有着相似的条目(数字)的一个长长的清单。当用户从一个组合框中选择一个项目时,我知道用户将从其他组合框中选择一个具有相似值(但可能不相同)的项目。因此,在用户选择了一个值后,为了避免强迫用户做大量滚动操作,我想“自动滚动”下一个组合框下拉到最后一个选定值的附近(当此下拉菜单还没有时一个选择)。理想情况下,我希望滚动位置设置为使最后选定的值出现在下拉列表的中间。如何设置一个WinForms组合框下拉滚动条的位置
到目前为止,我还试图通过设置在下落事件所选择的项目要做到这一点,但它有自己problems。有没有办法设置下拉的滚动位置而不必选择一个项目?
到目前为止,我已经试过这样:
[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不起作用。
我不知道你想完全实现的话,但你为什么不只是重新选择列表,以便最后选择项目首次出现? (或者只有它的两个副本 - 一个在正常位置,一个在正常位置) –
因为用户可能会选择与上次选择的项目不同的项目 - 但不同的项目将*关闭*到最后一个选定的项目。我试图选择最后一个项目,但就像我说的问题有其自己的问题(请参阅:http://stackoverflow.com/questions/12640438/detecting-user-selection-in-combobox-dropdownclosed-in -winforms) – Jimmy