How to change which item is “outlined” in a ListBox without changing the selection?
-
26-09-2019 - |
Question
How do you change which item is “outlined” in a ListBox? See the following screenshot for clarification:
Background: I want to have a standard multi-select listbox that works normally. Unfortunately, the Windows Forms ListBox (with SelectionMode.MultiExtended
) is not fully functional. The missing functionality is that it doesn’t let you select a disjoint set of items by using Ctrl+Arrow keys and Ctrl+Space. (Try it in Windows Explorer to see how it’s supposed to work.) I am trying to subclass ListBox and add this missing functionality. To this end, I intend to respond to Ctrl+Arrow keys in the OnKeyDown
protected method, but in order to do so, I need to be able to move the outline without changing the set of selected items. How do I do that?
Solution
You can do this by sending the LB_SETCARETINDEX message to the list box:
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern uint SendMessage(IntPtr hWnd, uint msg, uint wParam, uint lParam);
public const uint LB_SETCARETINDEX = 0x019E;
public const uint LB_GETCARETINDEX = 0x019F;
[...]
public int OutlineIndex
{
get
{
return (int) WinAPI.SendMessage(Handle, WinAPI.LB_GETCARETINDEX, 0, 0);
}
set
{
if (value < 0 || value >= Items.Count)
throw new ArgumentException("OutlineIndex cannot be negative or greater than the size of the collection.", "value");
WinAPI.SendMessage(Handle, WinAPI.LB_SETCARETINDEX, (uint) value, 0);
}
}