ToolStrip中自定义ComboBox的MeasureItem事件未触发,无法设置项大小问题求助
Alright, let's fix up your ToolStripComboBox issue—here's what's going wrong and how to fix it:
1. Why MeasureItem isn't firing
You set DrawMode.OwnerDrawFixed, which tells the ComboBox all dropdown items should have the same fixed height. This mode doesn't trigger the MeasureItem event because it doesn't need to calculate individual heights. Switch to DrawMode.OwnerDrawVariable instead—this is the mode that lets you customize each item's size via MeasureItem.
2. Your MeasureItem case logic is broken
You're checking against string values like "1", but e.Index is an integer that starts at 0 (for the first item in the list). Those conditions will never match, so even if MeasureItem fired, your custom heights wouldn't apply. Use integer indices instead.
3. You might get a crash in DrawItem
When the ComboBox first loads, DrawItem can fire with e.Index = -1 (no item selected yet). Trying to access cmbFontStyle.Items(e.Index) in that scenario will throw an error—add a quick check to avoid this.
Here's the corrected code for each part:
First, update your form load method to set the right DrawMode first:
Private Sub frmCorpusManagement_Load(sender As Object, e As EventArgs) Handles MyBase.Load ' Set DrawMode BEFORE loading items/binding events cmbFontStyle.ComboBox.DrawMode = DrawMode.OwnerDrawVariable LoadcmbFontStyle() AddHandler cmbFontStyle.ComboBox.DrawItem, AddressOf cmbFontStyle_DrawItem AddHandler cmbFontStyle.ComboBox.MeasureItem, AddressOf cmbFontStyle_MeasureItem End Sub
Fixed MeasureItem with valid integer indices (adjusted heights to actually fit your fonts—10px was way too small for a 12pt font):
Private Sub cmbFontStyle_MeasureItem(ByVal sender As Object, ByVal e As MeasureItemEventArgs) Select Case e.Index Case 0 ' Titre 1 (18pt bold) e.ItemHeight = 30 Case 1 ' Titre 2 (16pt bold underline) e.ItemHeight = 28 Case 2 ' Titre 3 (14pt bold underline) e.ItemHeight = 26 Case 3 ' Titre 4 (12pt underline) e.ItemHeight = 24 Case 4 ' Corps de Texte (12pt regular) e.ItemHeight = 22 End Select End Sub
DrawItem with a guard clause to prevent crashes:
Private Sub cmbFontStyle_DrawItem(ByVal sender As Object, ByVal e As DrawItemEventArgs) e.DrawBackground() ' Only render if we have a valid item index If e.Index >= 0 AndAlso e.Index < cmbFontStyle.Items.Count Then Dim myItem As CorpusFontStyleItem = DirectCast(cmbFontStyle.Items(e.Index), CorpusFontStyleItem) ' Use e.Bounds to position text properly within the item's area e.Graphics.DrawString(myItem.strTextStyleName, myItem.fontTextStyle, Brushes.Black, e.Bounds) End If e.DrawFocusRectangle() End Sub
One quick extra tip: Make sure you dispose of your Font objects when you're done with them (like in the form's FormClosing event) to avoid memory leaks. You can wrap their creation in Using blocks if you're creating them dynamically, but for your global fonts, just call CorpusFontStyleTitre1.Dispose() etc. when the form closes.
内容的提问来源于stack exchange,提问作者8oris

