Click here to Skip to main content
15,881,882 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have 4 combo boxes in my UI. The first one (CmbProject) doesn't flicker while updating, but the other 3 (CmbCustomer, CmbLocation, and CmbPlcName) do flicker while updating. I believe the problem has to do with the one thing they have in common: a timer (sub Timer1_tick). When I change the CmbCustomer: CmbLocation and CmbPlcName flicker. When CmbLocation is changed: CmbPlcName flickers. Nothing flickers when CmbPlcName changes.

I've trimmed some code. Exit App and the like.

VB
Imports System.ComponentModel

Public Class FrmSiCentral
    Public Property Customer As String
    Public Property Location As String
    Public Property Project As String
    Public Property PlcName As String
    Private Desc As String
    Private SQL As New SQL
    Private Version As Integer
    Private WithEvents Hardware As FrmHardwareEditor

    Private Sub CmbCustomer_SelectedIndexChanged(sender As Object, e As EventArgs) Handles CmbCustomer.SelectedIndexChanged

        ' When something  is selected in the Customer combobox this will read selection and load next combo box
        Customer = CmbCustomer.Text
        CmbLocation.Text = ""
        CmbLocation.Items.Clear()
        CmbPlcName.Text = ""
        CmbPlcName.Items.Clear()
        TextLoad("Location", CmbLocation, True)
    End Sub

    Private Sub TextLoad(name As String, target As ComboBox, Optional ByVal _Client As Boolean = False, Optional ByVal _Location As Boolean = False, Optional ByVal _PlcName As Boolean = False, Optional ByVal _Project As Boolean = False)

        ' SQL query tool
        If _Project = True Then
            SQL.ExecQuery("SELECT DISTINCT " & name & " FROM pProject WHERE WBS1='" & Project & "' ORDER BY " & name & " ASC;")
        ElseIf _Client = True AndAlso _Location = True AndAlso _PlcName = True Then
            SQL.ExecQuery("SELECT DISTINCT " & name & " FROM pProject WHERE Customer='" & Customer & "' AND Location='" &
                              Location & "' AND WBS1='" & Project & "' ORDER BY " & name & " ASC;")
        ElseIf _Client = True AndAlso _Location = True Then
            SQL.ExecQuery("SELECT DISTINCT " & name & " FROM pProject WHERE Customer='" & Customer & "' AND Location='" &
                          Location & "' ORDER BY " & name & " ASC;")
        ElseIf _Client = True Then
            SQL.ExecQuery("SELECT DISTINCT " & name & " FROM pProject WHERE Customer='" & Customer & "' ORDER BY " & name & " ASC;")
        Else
            SQL.ExecQuery("SELECT DISTINCT " & name & " FROM pProject ORDER BY " & name & " ASC;")
        End If

        If SQL.HasException(True) Then Exit Sub

        ' Go through data and put in combobox
        target.Items.Clear()
        For Each r As DataRow In SQL.DBDT.Rows
            target.Items.Add(r(name).ToString)
        Next
    End Sub

    Private Sub CmbLocation_SelectedIndexChanged(sender As Object, e As EventArgs) Handles CmbLocation.SelectedIndexChanged

        ' When something  is selected in the Location combobox this will read selection and load next combo box
        Location = CmbLocation.Text
        CmbPlcName.Text = ""
        CmbPlcName.Items.Clear()
        TextLoad("PLC_Name", CmbPlcName, True, True)
    End Sub

    Private Sub CmbPlcName_SelectedIndexChanged(sender As Object, e As EventArgs) Handles CmbPlcName.SelectedIndexChanged
        ' When something  is selected in the PLC name combobox this will read selection and load next combo box
        PlcName = CmbPlcName.Text
    End Sub

    Private Sub CmbPlcName_TextChanged(sender As Object, e As EventArgs) Handles CmbPlcName.TextChanged
        Timer1.Stop()
        Timer1.Start()
    End Sub

    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick

        Timer1.Stop()
        If CmbCustomer.Text <> "" AndAlso CmbLocation.Text <> "" AndAlso CmbPlcName.Text <> "" Then
            Customer = CmbCustomer.Text
            Location = CmbLocation.Text
            PlcName = CmbPlcName.Text

            ' Check what services are provided for project
            SQL.AddParam("@Customer", Customer)
            SQL.AddParam("@Location", Location)
            SQL.AddParam("@PLC_Name", PlcName)
            SQL.ExecQuery("SELECT JobDesc, Panel_Service, Eng_Service, Prog_Service,
                        SU_Service FROM pProject WHERE Customer=@Customer AND 
                        Location=@Location AND PLC_Name=@PLC_Name")
            If SQL.HasException(True) Then Exit Sub
            For Each r In SQL.DBDT.Rows
                Desc = r("JobDesc")
                CheckService(r, "Panel_Service", CbPanel)
                CheckService(r, "Eng_Service", CbEng)
                CheckService(r, "Prog_Service", CbProg)
                CheckService(r, "SU_Service", CbStartUp)
            Next
            TxtDesc.Text = Desc
        End If
    End Sub

    Private Sub CheckService(ByVal row As DataRow, service As String, obj As Object)

        Dim result As Integer
        If IsDBNull(row(service)) Then
            obj.Checked = False
        Else
            result = row(service)
            If result = 0 Then
                obj.Checked = False
            Else
                obj.Checked = True
            End If
        End If
    End Sub

    Private Sub CmbCustomer_TextChanged(sender As Object, e As EventArgs) Handles CmbCustomer.TextChanged
        Timer1.Stop()
        Timer1.Start()
    End Sub

    Private Sub CmbLocation_TextChanged(sender As Object, e As EventArgs) Handles CmbLocation.TextChanged
        Timer1.Stop()
        Timer1.Start()
    End Sub

    Private Sub FrmSiCentral_Shown(sender As Object, e As EventArgs) Handles Me.Shown

        ' This code is ran when the app launches
        If My.Application.CommandLineArgs.Any Then
            ' This processes any command line arguements passed to it by the Excel Spreadsheet
            CommandLineArgs()
        Else
            ' Otherwise load customers into the customers dropdown list
            TextLoad("Customer", CmbCustomer)
            TextLoad("WBS1", CmbProject)
        End If
    End Sub

    Private Sub CmbProject_SelectedIndexChanged(sender As Object, e As EventArgs) Handles CmbProject.SelectedIndexChanged

        If CmbProject.Text <> "" Then
            Project = CmbProject.Text
            CmbCustomer.Text = ""
            CmbCustomer.Items.Clear()
            CmbLocation.Text = ""
            CmbLocation.Items.Clear()
            CmbPlcName.Text = ""
            CmbPlcName.Items.Clear()
            TextLoad("Customer", CmbCustomer, _Project:=True)
        End If
    End Sub

    Private Sub BtnReset_Click(sender As Object, e As EventArgs) Handles BtnReset.Click

        Customer = ""
        CmbCustomer.BeginUpdate()
        CmbCustomer.Items.Clear()
        CmbCustomer.Text = ""
        Project = ""
        CmbProject.BeginUpdate()
        CmbProject.Items.Clear()
        CmbProject.Text = ""
        Location = ""
        CmbLocation.BeginUpdate()
        CmbLocation.Items.Clear()
        CmbLocation.Text = ""
        CmbLocation.EndUpdate()
        PlcName = ""
        CmbPlcName.BeginUpdate()
        CmbPlcName.Items.Clear()
        CmbPlcName.Text = ""
        CmbPlcName.EndUpdate()
        Desc = ""
        TxtDesc.Text = ""
        TextLoad("Customer", CmbCustomer)
        CmbCustomer.EndUpdate()
        TextLoad("WBS1", CmbProject)
        CmbProject.EndUpdate()
    End Sub

    Private Sub FrmSiCentral_Load(sender As Object, e As EventArgs) Handles Me.Load
        Me.GetStyle(ControlStyles.OptimizedDoubleBuffer = True)
    End Sub
End Class


What I have tried:

I added the doublebuffer style to the form on load and I've tried adding beginupdate() and endupdate() to a reset button near the bottom of the code and to the timer tick. When the Reset button is pressed there is no difference and all 3 Combo Boxes flicker.
Posted
Updated 12-May-20 3:58am
v2
Comments
[no name] 11-May-20 18:15pm    
They "flicker" because you clear and reload them instead of using a proper "update" cycle.
Inaruslynx 11-May-20 23:17pm    
So a good solution would be to loop through the items and delete all of them and then add items to the combo box? Should be easy enough. I'll give this a try tomorrow.
ZurdoDev 12-May-20 9:49am    
What would a proper update cycle be?
Inaruslynx 12-May-20 9:54am    
I changed the Sub TextLoad so that the user variables are now parameterized.

1 solution

Added the following Sub:

VB
Private Sub ClearCombo(target As ComboBox)
    While target.Items.Count > 0
        target.Items.RemoveAt(0)
    End While
End Sub


Replaced all ComboBox.Items.Clear() with this Sub. Combo Boxes no longer flicker.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900