In a Windows.Forms.ListBox
with the property DrawMode
set to OwnerDrawVariable
, the ListBox
seems to cache the height of the items, what is good.
BUT, being the item height dependent of the width, because it uses Graphics.MeasureString
to do word wrap, needs to calculate the height of items if the size of the ListBox
has changed. Then there's a problem.
The ListBox
doesn't do this by default, and I can't find a method to clear the cache, forcing the ListBox
to raise the itemheight event.
Any solution? I tried to get the source for the ListBox but don't find anything about that to make a derived class and clear this cache.
(Tried copying the items to an array, clearing the ListBox.Items
, and tem adding the array again. This even throw exceptions as the ListBox
calling the drawitem or itemheight events with invalid item index)
According this MSDN
LB_SETITEMHEIGHT message
Sets the height, in pixels, of items in a list box. If the list box has the
LBS_OWNERDRAWVARIABLE style, this message sets the height of the item
specified by the wParam parameter. Otherwise, this message sets the height
of all items in the list box.
So this will do it
private const int LB_SETITEMHEIGHT = 0x01A0;
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam);
private void ListBoxExample_Resize(object sender, EventArgs e)
{
for (int i = 0; i < ListBoxExample.Items.Count; i++)
{
MeasureItemEventArgs eArgs = new MeasureItemEventArgs(null, i);
ListBoxExample_MeasureItem((object)ListBoxExample, eArgs);
SendMessage((IntPtr) ListBoxExample.Handle, LB_SETITEMHEIGHT, (IntPtr) i, (IntPtr) e.ItemHeight);
}
}
The MeasureItemEventArgs
accepts a Graphics
object, if necessary, create one from the control and pass it in the first argument.