Inaruslynx Ответов: 1

Часть из них VB.NET мерцание пользовательского интерфейса


У меня есть 4 поля со списком в моем пользовательском интерфейсе. Первый (CmbProject) не мерцает при обновлении, но другие 3 (CmbCustomer, CmbLocation и CmbPlcName) мерцают при обновлении. Я считаю, что проблема связана с одной общей вещью: таймером (sub Timer1_tick). Когда я меняю CmbCustomer: CmbLocation и CmbPlcName мерцают. При изменении CmbLocation: CmbPlcName мерцает. Ничто не мерцает, когда CmbPlcName изменяется.

Я урезал кое-какой код. Выход из приложения и тому подобное.

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


Что я уже пробовал:

Я добавил стиль doublebuffer в форму при загрузке и попытался добавить beginupdate() и endupdate() к кнопке сброса в нижней части кода и к отметке таймера. Когда кнопка сброса нажата, разницы нет, и все 3 поля со списком мерцают.

Gerry Schmitz

Они "мерцают", потому что вы очищаете и перезагружаете их вместо того, чтобы использовать правильный цикл "обновления".

Inaruslynx

Таким образом, хорошим решением было бы перебирать элементы и удалять их все, а затем добавлять элементы в поле со списком? Это должно быть достаточно просто. Я попробую сделать это завтра.

ZurdoDev

Каким будет правильный цикл обновления?

Inaruslynx

Я изменил Субтекстовую загрузку так, чтобы пользовательские переменные теперь были параметризованы.

1 Ответов

Рейтинг:
4

Inaruslynx

Добавлен следующий подпункт:

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


Заменил все ComboBox.Предметы.Clear() с этой субмариной. Комбинированные поля больше не мерцают.