Hello,
I was implementing an owner-draw ComboBox, which should render long items multiline. I'm using MeasureItem and DrawItem the following way (important lines marked with comments):
class MultiLineComboBox : ComboBox {
...
protected override void InitLayout() // (1) Method selection explained below. { base.InitLayout(); MeasureItem += new MeasureItemEventHandler(MultiLineComboBox_MeasureItem); DrawItem += new DrawItemEventHandler(MultiLineComboBox_DrawItem); } void MultiLineComboBox_MeasureItem(object sender, MeasureItemEventArgs e) { string itemText = Items[e.Index].ToString(); int textWidth = DropDownWidth - ItemPadding.Horizontal - SystemInformation.VerticalScrollBarWidth; e.ItemHeight = ItemPadding.Vertical + (int)(e.Graphics.MeasureString(itemText, Font, textWidth).Height); e.ItemWidth = ItemPadding.Horizontal + textWidth; // (2) } void MultiLineComboBox_DrawItem(object sender, DrawItemEventArgs e) { if (e.Index < 0) return; e.DrawBackground(); e.Graphics.DrawString( // (3) Items[e.Index].ToString(), Font, SystemBrushes.FromSystemColor(e.ForeColor), e.Bounds, itemFormat); }
}
The first problem is, when I set item width to, say, 250 at (2), I get, say, 350 as e.Bounds.Width at (3) --- actual numbers vary --- so that I draw the text into a wider rectangle than it was supposed to. My best guess is that MeasureItem is raised before DropDownWidth is set to a correct value. So, my question is: where do I have to place subscribtion to this event in order to perform measurment with proper values?
Placing the ComboBox inside a UserControl and subscribtion in OnLoad of the latter may help (though I'd prefer to subclass ComboBox), but this won't solve the second question: how do I issue a command for windows to measure all the items again (raising MeasureItem) when the ComboBox is resized, for example?
Thanks in advance.