0

Environnement:

  • OS: Windows 10
  • Visual Studio : VS 2019 Up to date Application: Full
  • .NET 5.0
  • VB.NET with some third part libraries

Situation: I got an exception having came from nowhere on a toolstrip combobox add item method (first cmbFontStyle.Items.Add):

Public Class MyForm
Private FontStyleTitre1 As Font = New Font(New FontFamily("Lato"), 18, FontStyle.Bold, 3)
Private FontStyleTitre2 As Font = New Font(New FontFamily("Lato"), 16, FontStyle.Underline Or FontStyle.Bold, 3)
Private FontStyleTitre3 As Font = New Font(New FontFamily("Lato"), 14, FontStyle.Underline Or FontStyle.Bold, 3)
Private FontStyleTitre4 As Font = New Font(New FontFamily("Lato"), 12, FontStyle.Underline, 3)
Private FontStyleCorpsdeTexte As Font = New Font(New FontFamily("Lato"), 10, FontStyle.Regular, 3)
Private Sub frmCorpusManagement_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        cmbFontStyle.ComboBox.DrawMode = DrawMode.OwnerDrawVariable
        AddHandler cmbFontStyle.ComboBox.DrawItem, AddressOf cmbFontStyle_DrawItem
        AddHandler cmbFontStyle.ComboBox.MeasureItem, AddressOf cmbFontStyle_MeasureItem
        LoadcmbFontStyle()

End Sub

Private Sub LoadcmbFontStyle()
        Dim strMsgException As String = "Erreur dans le module LoadcmbFontStyle" & vbCrLf & "Impossible d'afficher la liste des corpus documentaires " & vbCrLf & vbCrLf & strMsgErrorTellYourAdmin & vbCrLf & vbCrLf & "-- Message d'erreur: "

        Dim itemCorpusFontStyleTitre1 As New CorpusFontStyleItem With {.strTextStyleName = "Titre 1", .fontTextStyle = FontStyleTitre1}
        Dim itemCorpusFontStyleTitre2 As New CorpusFontStyleItem With {.strTextStyleName = "Titre 2", .fontTextStyle = FontStyleTitre2}
        Dim itemCorpusFontStyleTitre3 As New CorpusFontStyleItem With {.strTextStyleName = "Titre 3", .fontTextStyle = FontStyleTitre3}
        Dim itemCorpusFontStyleTitre4 As New CorpusFontStyleItem With {.strTextStyleName = "Titre 4", .fontTextStyle = FontStyleTitre4}
        Dim itemCorpusFontStyleCorps As New CorpusFontStyleItem With {.strTextStyleName = "Corps de Texte", .fontTextStyle = FontStyleCorpsdeTexte}

        Try
            cmbFontStyle.Items.Add(itemCorpusFontStyleTitre1)
            cmbFontStyle.Items.Add(itemCorpusFontStyleTitre2)
            cmbFontStyle.Items.Add(itemCorpusFontStyleTitre3)
            cmbFontStyle.Items.Add(itemCorpusFontStyleTitre4)
            cmbFontStyle.Items.Add(itemCorpusFontStyleCorps)

        Catch ex As Exception
            MsgBox(strMsgException & ex.Message, MsgBoxStyle.Critical, strMsgBoxCorpusDocTitleError)
            Exit Try

        End Try

    End Sub
End Class

I guess it's some of these current "cryptic" issues.

Some links:

Resolution:

I tried:

  • adding a new environment variable: doesn't do anything
  • run VS as administrator: doesn't do anything
  • add a try/catch: doesn't do anything
  • uncheck the "Suppress JIT optimization on module load" option (Tools/Options/Debugging/General): doesn't do anything.
  • switch the DropDownStyle between DropDown and DropDownList: doesn't do anything

I did not try:

  • tweaking the CPU options

What it worked the best was to add cmbFontStyle.Items.Clear() before the first cmbFontStyle.Items.Add

It works but not every time.

I don't get it. If anyone has suggestions or ideas...

EDIT: Following Jimi advices:

Option Strict On
Imports MySql.Data.Types
Imports MySql.Data.MySqlClient
Imports System.Text.RegularExpressions
Imports System.Text
Imports System.IO
Imports System.ComponentModel
Imports System.Drawing

Public Class frmCorpusManagement
    Private WithEvents frmCorpusAddObjectNew As frmCorpusAddObject
    Private frmWaitingCorpus As New frmTechWaiting
    Private objectToAdd As FormatedObjectForCorpus
    Private blnLoadInProgress As Boolean
    Private graphicUnitUsed As GraphicsUnit = GraphicsUnit.Point
    Private intcmbFontStyleTotalHeight As Integer
    Private FontStyleTitre1 As Font = New Font(New FontFamily("Lato"), 18, FontStyle.Bold, graphicUnitUsed)
    Private FontStyleTitre2 As Font = New Font(New FontFamily("Lato"), 16, FontStyle.Underline Or FontStyle.Bold, graphicUnitUsed)
    Private FontStyleTitre3 As Font = New Font(New FontFamily("Lato"), 14, FontStyle.Underline Or FontStyle.Bold, graphicUnitUsed)
    Private FontStyleTitre4 As Font = New Font(New FontFamily("Lato"), 12, FontStyle.Underline, graphicUnitUsed)
    Private FontStyleCorpsdeTexte As Font = New Font(New FontFamily("Lato"), 10, FontStyle.Regular, graphicUnitUsed)
    Private FontStyleForDisplay As Font = New Font(New FontFamily("Lato"), 9, FontStyle.Regular, graphicUnitUsed)

    Private Sub frmCorpusManagement_Load(sender As Object, e As EventArgs) Handles MyBase.Load      
        cmbFontStyle.ComboBox.DrawMode = DrawMode.OwnerDrawVariable
        AddHandler cmbFontStyle.ComboBox.DrawItem, AddressOf cmbFontStyle_DrawItem
        AddHandler cmbFontStyle.ComboBox.MeasureItem, AddressOf cmbFontStyle_MeasureItem
        LoadcmbFontStyle()
        cmbFontStyle.SelectedIndex = cmbFontStyle.Items.Count - 1
    End Sub
    
    Private Sub frmCorpusAddObject_evtObjectLinkFormated(sender As Object, e As EventArgs) Handles frmCorpusAddObjectNew.evtObjectLinkFormated
        Dim objectToAddFormated As New FormatedObjectForCorpus
        Dim strMsgException As String = "Erreur dans le Module frmCorpusAddObject_evtObjectLinkFormated" & vbCrLf & strMsgErrorTellYourAdmin & vbCrLf & vbCrLf & "-- Message d'erreur: "
        Try
            objectToAddFormated = frmCorpusAddObjectNew.objectToAddFormated
            rtxtCorpusContent.InsertLink(objectToAddFormated.strText, objectToAddFormated.strLink)
            Me.frmCorpusAddObjectNew.Close()
            Exit Try
        Catch ex As Exception
            MsgBox(strMsgException & ex.Message, MsgBoxStyle.Critical, strMsgBoxCorpusDocTitle)
        End Try
    End Sub
    
    Private Sub cmbFontStyle_MeasureItem(ByVal sender As Object, ByVal e As MeasureItemEventArgs)
        Select Case e.Index
            Case 0
                e.ItemHeight = CInt(FontStyleTitre1.Height)
                intcmbFontStyleTotalHeight += e.ItemHeight
            Case 1
                e.ItemHeight = CInt(FontStyleTitre2.Height)
                intcmbFontStyleTotalHeight += e.ItemHeight
            Case 2
                e.ItemHeight = CInt(FontStyleTitre3.Height)
                intcmbFontStyleTotalHeight += e.ItemHeight
            Case 3
                e.ItemHeight = CInt(FontStyleTitre4.Height)
                intcmbFontStyleTotalHeight += e.ItemHeight
            Case 4
                e.ItemHeight = CInt(FontStyleCorpsdeTexte.Height)
                intcmbFontStyleTotalHeight += e.ItemHeight
        End Select
        cmbFontStyle.DropDownHeight = intcmbFontStyleTotalHeight
    End Sub
    
    Private Sub cmbFontStyle_DrawItem(ByVal sender As Object, ByVal e As DrawItemEventArgs)
        e.DrawBackground()
        Dim myItem As CorpusFontStyleItem = DirectCast(cmbFontStyle.Items(e.Index), CorpusFontStyleItem)
        e.Graphics.DrawString(myItem.strTextStyleName, myItem.fontTextStyle, New SolidBrush(Color.Black), e.Bounds)
        e.DrawFocusRectangle()
    End Sub
    
    Private Sub LoadcmbFontStyle()
        Dim strMsgException As String = "Erreur dans le module LoadcmbFontStyle" & vbCrLf & "Impossible d'afficher la liste des corpus documentaires " & vbCrLf & vbCrLf & strMsgErrorTellYourAdmin & vbCrLf & vbCrLf & "-- Message d'erreur: "
        Dim lstComboFontStyle As New List(Of CorpusFontStyleItem)

        Try
            lstComboFontStyle.Add(New CorpusFontStyleItem With {.strTextStyleName = "Titre 1", .fontTextStyle = FontStyleTitre1})
            lstComboFontStyle.Add(New CorpusFontStyleItem With {.strTextStyleName = "Titre 2", .fontTextStyle = FontStyleTitre2})
            lstComboFontStyle.Add(New CorpusFontStyleItem With {.strTextStyleName = "Titre 3", .fontTextStyle = FontStyleTitre3})
            lstComboFontStyle.Add(New CorpusFontStyleItem With {.strTextStyleName = "Titre 4", .fontTextStyle = FontStyleTitre4})
            lstComboFontStyle.Add(New CorpusFontStyleItem With {.strTextStyleName = "Corps de Texte", .fontTextStyle = FontStyleCorpsdeTexte})
            With Me.cmbFontStyle.ComboBox
                .DisplayMember = "strTextStyleName"
                .ValueMember = "strTextStyleName"
                .DataSource = lstComboFontStyle
            End With

        Catch ex As Exception
            MsgBox(strMsgException & ex.Message, MsgBoxStyle.Critical, strMsgBoxCorpusDocTitleError)
            Exit Try

        End Try

    End Sub
8oris
  • 320
  • 2
  • 12
  • I think you have already asked this question (or similar). I don't think you have picked up any of the suggestions. -- Setting `DrawMode.OwnerDrawVariable`, the text of each item is decided in the `DrawItem` handler, where you access the actual objects that each Item contains. -- You should have a `List(Of Class)` (where `Class` is `CorpusFontStyleItem`), set this list as the DataSource of your ComboBox and *explicitly* set the `DisplayMember` and `ValueMember` properties. – Jimi Dec 16 '21 at 13:06
  • I've already had issues on this part of my code and asked questions about it but here, it's a totally different issue. Moreover, i've read answers to my previous questions and followed it as far as i can. Whatever, i tried to bind the comboxbox as you adviced me to do even if the way i've populate the combobox doesn't seems to be an issue considering that it worked sometimes... – 8oris Dec 16 '21 at 13:24
  • Well, show the code that tries that (setting the DataSource with a collection of Class objects) and add the code executed in the `DrawItem` and `MeasureItem` handlers. -- You're looking for the source of the problem in the wrong places. – Jimi Dec 16 '21 at 13:26
  • I edited and add some of your suggestions. Same exception, same message, same erratic behaviour. This time, it's located on ```.DataSource = bsComboFontStyle``` – 8oris Dec 16 '21 at 14:05
  • All right. `DisplayMember` and `ValueMember` are still not set and the fixed measures in `MeasureItem` are inconsistent. But, what are `cmbFontStyle` and `cmbFontStyle.ComboBox`? What is your ComboBox? – Jimi Dec 16 '21 at 14:27
  • I'm sorry but I don't get why ```DisplayMember``` and ```ValueMember``` would be still not set. ```cmbFontStyle``` is a combobox in toolstripcombobox, hence the use of ```cmbFontStyle.ComboBox``` – 8oris Dec 16 '21 at 14:35
  • They're not set because you haven't set them :) Set those property values to the corresponding properties (e.g., `cmbFontStyle.ComboBox.DisplayMember = "strTextStyleName"`), **before** you set the DataSource. Remove the local variables, the BindingSource and add the class objects directly to the list: e.g., `lstComboFontStyle.Add(New CorpusFontStyleItem With {.strTextStyleName = "Titre 1", .fontTextStyle = FontStyleTitre1})` -- The Items height measure is *inconsistent*: get the Item's Font height -- Also - quite important - set `Option Strict On` and fix the errors that pop up. – Jimi Dec 16 '21 at 14:58
  • It's also important that you specify the objects you're working with in detail: you didn't say that the ComboBox is a ToolStrip component. Yes, it's still a ComboBox, but there's a subtle difference in .Net 5+. – Jimi Dec 16 '21 at 15:00
  • Sorry about the lack of specification concerning the combobox. It's edited. I have followed all your wise advices and i have edited the "EDIT: Following Jimi advices:" part in the original post. By the way: i always got the cryptic "memory error" issue. :] – 8oris Dec 16 '21 at 15:40
  • The `ValueMember` is wrong, should be `cmbFontStyle.ComboBox.ValueMember = "fontTextStyle"` and, as mentioned, the `MeasureItem` event generates inconsistent measures (also, the same Item index can be queried multiple times). Try to comment out everything except `e.ItemHeight = 40` -- Possibly, remove all code that has nothing to do with the issue. – Jimi Dec 16 '21 at 16:03
  • Instead of creating six identical FontFamily instances, declare a variable (`Private ReadOnly LatoFontFamily As New FontFamily("Lato")`) and then use that variable to declare the fonts (i.e. `Private FontStyleTitre1 As New Font(LatoFontFamily, 18, FontStyle.Bold, GraphicsUnit.Point)`). Note the use of `GraphicsUnit.Point` instead of the _magic number_ 3 ; using the Enum will make your code easier to read. These changes may not solve the problem, but it eliminates the possibility that multiple FontFamily instances with their underlying resources are the cause of the memory conflict. – TnTinMn Dec 16 '21 at 17:57
  • @TnTinMn It's just this: `intcmbFontStyleTotalHeight += e.ItemHeight` + `cmbFontStyle.DropDownHeight = intcmbFontStyleTotalHeight`. It doesn't take into consideration how and when the `MeasureItem` event is actually called. The exception you receive is somewhat misleading. -- The other suggestions I gave are just meant to make the whole thing work better. – Jimi Dec 17 '21 at 06:11
  • @TnTinMn : thanks for your suggestions which i followed but i still got the "memory" exception located in the same place: when the toolstrip combobox datasource is set. – 8oris Dec 17 '21 at 09:16

0 Answers0