Часть из них 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
Каким будет правильный цикл обновления?
Richard Deeming
Ваш код уязвим для SQL-инъекция[^]. НИКОГДА используйте конкатенацию строк для построения SQL-запроса. ВСЕГДА используйте параметризованный запрос.
Все, что вы хотели знать о SQL-инъекции (но боялись спросить) | Трой Хант[^]
Как я могу объяснить SQL-инъекцию без технического жаргона? | Обмен Стеками Информационной Безопасности[^]
Шпаргалка по параметризации запросов | OWASP[^]
Inaruslynx
Я изменил Субтекстовую загрузку так, чтобы пользовательские переменные теперь были параметризованы.