Is it possible to do this code with less redundancy? - vb.net

I have the following code:
If moves.Contains("1") Then
lblOnes.Visible = True
End If
If moves.Contains("2") Then
lblTwos.Visible = True
End If
If moves.Contains("3") Then
lblThrees.Visible = True
End If
If moves.Contains("4") Then
lblFours.Visible = True
End If
If moves.Contains("5") Then
lblFives.Visible = True
End If
If moves.Contains("6") Then
lblSixes.Visible = True
End If
I just feel like it is redundant, is there any way to do this without repeating the same statement over and over?

You could e.g. use a look up using a Dictionary:
Dim map = new Dictionary(Of String, Label) From
{
{"2", lblTwos},
{"3", lblThrees},
{"4", lblFours},
{"5", lblFives},
{"6", lblSixes}
}
For Each kvp In map
If moves.Contains(kvp.Key) Then
kvp.value.Visible = True
End If
Next
Other possible ways:
use the Tag property of the controls
name your controls lbl_1, lbl_2 etc. and loop over all elements in moves to find the right control by its name.

Another example:
Dim lbls() As Label = {lblOnes, lblTwos, lblThrees, lblFours, lblFives, lblSixes}
For i As Integer = 0 To lbls.Length - 1
If moves.Contains((i + 1).ToString) Then
lbls(i).Visible = True
Else
' ... possibly do something in here? ...
End If
Next

If you have the luxury of renaming your Labels from lblOnes, lblTwos etc. to lbl1s, lbl2s, then it would simply be:
For i = 1 To 6
Me.Controls("lbl" & i & "s").Visible = moves.Contains(i.ToString())
Next

I propose following idea:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim moves As String
moves = "1"
Dim controlName As String
controlName = "lbl" + moves
CType(Me.Controls("controlName"), Label).Visible = True
End Sub

Related

Streamreader not reading all lines

I am working on a little tool that allows the selection of a single file. Where it will calculate the SHA2 hash and shows it in a simple GUI then takes the value and checks if that hash is listed in a blacklist text file. If it is listed then it will flag it as dirty, and if not it will pass it as clean.
But after hitting Google for hours on end and sifting through many online sources I decided let's just ask for advise and help.
That said while my program does work I seem to run into a problem, since no matter what I do ,it only reads the first line of my "blacklist" and refuses to read the whole list or to actually go line by line to see if there is a match.
No matter if I got 100 or 1 SHA2 hash in it.
So example if I were to have 5 files which I add to the so called blacklist. By pre-calculating their SHA2 value. Then no matter what my little tool will only flag one file which is blacklisted as a match.
Yet the moment I use the reset button and I select a different (also blacklisted) file, it passes it as clean while its not. As far as I can tell it is always the first SHA2 hash it seems to flag and ignoring the others. I personally think the program does not even check beyond the first hash.
Now the blacklist file is made up very simple.
*example:
1afde1cbccd2ab36f90973cb985072a01ebdc64d8fdba6a895c855d90f925043
2afde1cbccd2ab36f90973cb985072a01ebdc64d8fdba6a895c855d90f925043
3afde1cbccd2ab36f90973cb985072a01ebdc64d8fdba6a895c855d90f925043
4afde1cbccd2ab36f90973cb985072a01ebdc64d8fdba6a895c855d90f925043
....and so on.
So as you can see these fake example hashes are listed without any details.
Now my program is suppose to calculate the hash from a selected file.
Example:
somefile.exe (or any extension)
Its 5KB in size and its SHA2 value would be:
3afde1cbccd2ab36f90973cb985072a01ebdc64d8fdba6a895c855d90f925043
Well as you can see I took the third hash from the example list right?
Now if I select somefile.exe for scanning then it will pass it as clean. While its blacklisted. So if I move this hash to the first position. Then my little program does correctly flag it.
So long story short I assume that something is horrible wrong with my code, even though it seems to be working.
Anyway this is what I got so far:
Imports System.IO
Imports System.Security
Imports System.Security.Cryptography
Imports MetroFramework.Forms
Public Class Fsmain
Function SHA256_SIG(ByVal file_name As String)
Return SHA256_engine("SHA-256", file_name)
End Function
Function SHA256_engine(ByRef hash_type As String, ByRef file_name As String)
Dim SIG
SIG = SHA256.Create()
Dim hashValue() As Byte
Dim filestream As FileStream = File.OpenRead(file_name)
filestream.Position = 0
hashValue = SIG.ComputeHash(filestream)
Dim hash_hex = PrintByteArray(hashValue)
Stream.Null.Close()
Return hash_hex
End Function
Public Function PrintByteArray(ByRef array() As Byte)
Dim hex_value As String = ""
Dim i As Integer
For i = 0 To array.Length - 1
hex_value += array(i).ToString("x2")
Next i
Return hex_value.ToLower
End Function
Private Sub Browsebutton_Click(sender As Object, e As EventArgs) Handles Browsebutton.Click
If SampleFetch.ShowDialog = DialogResult.OK Then
Dim path As String = SampleFetch.FileName
Selectfile.Text = path
Dim Sample As String
Sample = SHA256_SIG(path)
SignatureREF.Text = SHA256_SIG(path)
Using f As System.IO.FileStream = System.IO.File.OpenRead("blacklist.txt")
Using s As System.IO.StreamReader = New System.IO.StreamReader(f)
While Not s.EndOfStream
Dim line As String = s.ReadLine()
If (line = Sample) Then
Result.Visible = True
SignatureREF.Visible = True
Result.Text = "Dirty"
Resetme.Visible = True
RemoveMAL.Visible = True
Else
Result.Visible = True
SignatureREF.Visible = True
Result.Text = "Clean"
Resetme.Visible = True
RemoveMAL.Visible = False
End If
End While
End Using
End Using
End If
End Sub
Private Sub Fsmain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Result.Visible = False
SignatureREF.Visible = False
Resetme.Visible = False
RemoveMAL.Visible = False
End Sub
Private Sub Resetme_Click(sender As Object, e As EventArgs) Handles Resetme.Click
Selectfile.Text = Nothing
SignatureREF.Text = Nothing
Result.Visible = False
SignatureREF.Visible = False
Resetme.Visible = False
RemoveMAL.Visible = False
End Sub
Private Sub RemoveMAL_Click(sender As Object, e As EventArgs) Handles RemoveMAL.Click
Dim ask As MsgBoxResult = MsgBox("Would you like to remove the Dirty file?", MsgBoxStyle.YesNo, MessageBoxIcon.None)
If ask = MsgBoxResult.Yes Then
System.IO.File.Delete(Selectfile.Text$)
Else
MsgBox("You sure you want to keep this file?")
Dim filepath As String = IO.Path.Combine("c:\Dirty\", "Dirty.txt")
Using sw As New StreamWriter(filepath)
sw.WriteLine(" " & DateTime.Now)
sw.WriteLine(" " & Selectfile.Text)
sw.WriteLine(" " & SignatureREF.Text)
sw.WriteLine(" " & Result.Text)
sw.WriteLine("-------------------")
sw.Close()
End Using
End If
End Sub
End Class
So if any of you guys can have a look at it and point out errors, or even can come up with a fix that would be great.
The simplest thing you can do to make your procedure working, is testing whether a defined condition is verified. Terminate the test if that condition is met.
Using a boolean variable, report the result of the test and take action accordingly.
The Using statement takes care of disposing the StreamReader.
You could modify you procedure this way:
Private Sub Browsebutton_Click(sender As Object, e As EventArgs) Handles Browsebutton.Click
If SampleFetch.ShowDialog <> DialogResult.OK Then Exit Sub
Dim sample As String = SHA256_SIG(SampleFetch.FileName)
SignatureREF.Text = sample
Dim isDirty As Boolean = False
Using reader As StreamReader = New StreamReader("blacklist.txt", True)
Dim line As String = String.Empty
While reader.Peek() > 0
line = reader.ReadLine()
If line = sample Then
isDirty = True
Exit While
End If
End While
End Using
If isDirty Then
'(...)
RemoveMAL.Visible = True
Result.Text = "Dirty"
Else
'(...)
RemoveMAL.Visible = False
Result.Text = "Clean"
End If
End Sub
If you have a String and you want to test whether it matches a line of a text file then you can use this simple one-liner:
If IO.File.ReadLines(filePath).Contains(myString) Then

FInd a title by searching with only a portion of the text?

Title says it all, I need help making my search input box find the title and display it when the user only types part of the movie title before searching. This is what I have now and it works great, but you must type in the complete title. Any help would be appreciated! Thanks
Private Sub btnSearch_Click(sender As Object, e As EventArgs)Handles btnSearch.Click
'Searches for movie in listbox
Dim strDVDtitle As String
strDVDtitle = InputBox("Enter Movie Title:")
Dim X As Integer = 0
Dim bolDVDFound As Boolean = False
For X = 0 To count - 1
If DVDS(X).DVDtitle = strDVDtitle Then
txtDVDyear.Text = DVDS(X).DVDyear
txtDVDtitle.Text = DVDS(X).DVDtitle
txtDVDyear.Text = DVDS(X).DVDyear
txtDVDruntime.Text = DVDS(X).DVDruntime
txtDVDrating.Text = DVDS(X).DVDrating
bolDVDFound = True
End If
Next
If bolDVDFound = False Then
MessageBox.Show("Movie not found")
End If
End Sub
You can use the contains string method, like this:
Dim actualTitle = "The Martian"
If actualTitle.ToLower().Contains(strDVDtitle.ToLower()) Then
MsgBox("Match!")
End If

Array copy will not work in a if statement or by button click sub

I am trying to make a small log ( string array of 10 ) of time stamps that on a event will move the newest event towards the first string in the array.
Here is a few attempts that I have tried. The only time the array will change is when it is in a timer.
What Iam looking to do is
on a bit change to copy arrayA(1) to array(0). witch will move the string from (1) to (0),(2) to (1),(3) to (2) and the rest of the array. So when the event happens it cascades the strings to make a list of last events (0) would be the 10th event that happened and the (9) would be the first or latest event
Attempt 1
Private Sub RcvTmr_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RcvTmr.Tick
dim SrvUpTimeStgArray(9) as string
If BtnBit = False And OneShot(5) = True Then
OneShot(5) = False
SrvUpTimeStgArray(9) = LAtimeSvrUp.TimeString
For I = 0 To 8
SrvUpTimeStgArray(I) = SrvUpTimeStgArray(I + 1)
Next
LAtimeSvrUp.StopTimer()
End If
ListBox1.DataSource = SrvUpTimeStgArray
End Sub
Then this code to
Private Sub RcvTmr_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RcvTmr.Tick
Dim StringArrayA(9) as string : Dim StringArrayB(9) as string
If OneShot(10) = False Then
OneShot(10) = True
StringArrayA(3) = "testst 33333"
StringArrayA(2) = "testst 22222"
StringArrayA(1) = "testst 11111"
StringArrayA(0) = "testst 00000"
End If
StringArrayA(0) = StringArrayA(1)
If Btn1TestBit Then
counter1 = counter1 + 1
BtnTest3.Text = "worked"
'Call ArrayCopy()
Btn1TestBit = False
StringArrayA(0) = StringArrayA(1)
' The below was alternated with the above line ans also did not work
' Array.Copy(StringArrayA, 1, StringArrayB, 0, 4)
End If
ListBox1.DataSource = StringArrayA
ListBox2.DataSource = StringArrayB
Lacount3.Text = counter1
End Sub
I am missing something so thanks..
Update but It has duplicate strings to the array
This is using the AddLog Sub
If ClientConnBit = False And OneShot(5) = True Then
OneShot(5) = False
AddLog(SrvUpTimeStgArray, "Stopped # " & DateTime.Now.ToString() & "* Up Time " & LAtimeSvrUp.TimeString)
LAtimeSvrUp.StopTimer()
For Each entry As String In SrvUpTimeStgArray
If Not String.IsNullOrEmpty(entry) Then
LBSvrUptimeLog.Items.Add(entry)
End If
Next
'LBSvrUptimeLog.DataSource = SrvUpTimeStgArray
My.Settings.UpTimeString.AddRange(SrvUpTimeStgArray)
My.Settings.Save()
End If
You need to copy the values backward, if you do it forward you'll end up copying the same value everywhere. I suggest you load how to use break point and watch.
This is how it would look like
Sub AddLog(ByVal logAsArray() As String, ByVal newEntry As String)
For index As Integer = logAsArray.Length - 1 To 1 Step -1
logAsArray(index) = logAsArray(index - 1)
Next
logAsArray(0) = newEntry
End Sub
You can also use list instead
Sub AddLog(ByVal logAsList As List(Of String), ByVal newEntry As String)
If logAsList.Count = logAsList.Capacity Then
logAsList.RemoveAt(logAsList.Capacity - 1)
End If
logAsList.Insert(0, newEntry)
End Sub
Here's an example on how to use these functions.
Sub Main()
Dim logAsArray(2) As String
AddLog(logAsArray, "a")
AddLog(logAsArray, "b")
AddLog(logAsArray, "c")
AddLog(logAsArray, DateTime.Now.ToString())
For Each entry As String In logAsArray
Console.WriteLine(entry)
Next
Dim logAsList As New List(Of String)(3)
AddLog(logAsList, "a")
AddLog(logAsList, "b")
AddLog(logAsList, "c")
AddLog(logAsList, DateTime.Now.ToString())
For Each entry As String In logAsList
Console.WriteLine(entry)
Next
Console.ReadLine()
End Sub

What is wrong with my subroutines?

So I've been working on this project for a couple of weeks, as I self teach. I've hit a wall, and the community here has been so helpful I come again with a problem.
Basically, I have an input box where a user inputs a name. The name is then displayed in a listbox. The name is also put into an XML table if it is not there already.
There is a button near the list box that allows the user to remove names from the list box. This amends the XML, not removing the name from the table, but adding an end time to that name's child EndTime.
If the user then adds the same name to the input box, the XML gets appended to add another StartTime rather than create a new element.
All of this functions well enough (My code is probably clunky, but it's been working so far.) The problem comes when I try to validate the text box before passing everything through to XML. What I am trying to accomplish is that if the name exists in the listbox on the form (i.e hasn't been deleted by the user) then nothing happens to the XML, the input box is cleared. This is to prevent false timestamps due to a user accidentally typing the same name twice.
Anyhow, I hope that makes sense, I'm tired as hell. The code I've got is as follows:
Private Sub Button1_Click_2(sender As System.Object, e As System.EventArgs) Handles addPlayerButton.Click
playerTypeCheck()
addPlayerXML()
clearAddBox()
End Sub
Private Sub playerTypeCheck()
If playerTypeCBox.SelectedIndex = 0 Then
addMiner()
ElseIf playerTypeCBox.SelectedIndex = 1 Then
addHauler()
ElseIf playerTypeCBox.SelectedIndex = 2 Then
addForeman()
End If
End Sub
Private Sub addMiner()
If minerAddBox.Text = String.Empty Then
Return
End If
If minerListBox.Items.Contains(UCase(minerAddBox.Text)) = True Then
Return
Else : minerListBox.Items.Add(UCase(minerAddBox.Text))
End If
If ComboBox1.Items.Contains(UCase(minerAddBox.Text)) = True Then
Return
Else : ComboBox1.Items.Add(UCase(minerAddBox.Text))
End If
End Sub
Private Sub addPlayerXML()
If System.IO.File.Exists("Miners.xml") Then
Dim xmlSearch As New XmlDocument()
xmlSearch.Load("Miners.xml")
Dim nod As XmlNode = xmlSearch.DocumentElement()
If minerAddBox.Text = "" Then
Return
Else
If playerTypeCBox.SelectedIndex = 0 Then
nod = xmlSearch.SelectSingleNode("/Mining_Op/Miners/Miner[#Name='" + UCase(minerAddBox.Text) + "']")
ElseIf playerTypeCBox.SelectedIndex = 1 Then
nod = xmlSearch.SelectSingleNode("/Mining_Op/Haulers/Hauler[#Name='" + UCase(minerAddBox.Text) + "']")
ElseIf playerTypeCBox.SelectedIndex = 2 Then
nod = xmlSearch.SelectSingleNode("/Mining_Op/Foremen/Foreman[#Name='" + UCase(minerAddBox.Text) + "']")
End If
If nod IsNot Nothing Then
nodeValidatedXML()
Else
Dim docFrag As XmlDocumentFragment = xmlSearch.CreateDocumentFragment()
Dim cr As String = Environment.NewLine
Dim newPlayer As String = ""
Dim nod2 As XmlNode = xmlSearch.SelectSingleNode("/Mining_Op/Miners")
If playerTypeCBox.SelectedIndex = 0 Then
newMinerXML()
ElseIf playerTypeCBox.SelectedIndex = 1 Then
newHaulerXML()
ElseIf playerTypeCBox.SelectedIndex = 2 Then
newForemanXML()
End If
End If
End If
Else
newXML()
End If
End Sub
Private Sub nodeValidatedXML()
If playerTypeCBox.SelectedIndex = 0 Then
minerValidatedXML()
ElseIf playerTypeCBox.SelectedIndex = 1 Then
haulerValidatedXML()
ElseIf playerTypeCBox.SelectedIndex = 2 Then
foremanValidatedXML()
End If
End Sub
Private Sub minerValidatedXML()
If minerListBox.Items.Contains(UCase(minerAddBox.Text)) = False Then
appendMinerTimeXML()
End If
End Sub
Private Sub appendMinerTimeXML()
Dim xmlSearch As New XmlDocument()
xmlSearch.Load("Miners.xml")
Dim docFrag As XmlDocumentFragment = xmlSearch.CreateDocumentFragment()
Dim cr As String = Environment.NewLine
Dim newStartTime As String = Now & ", "
Dim nod2 As XmlNode = xmlSearch.SelectSingleNode("/Mining_Op/Miners/Miner[#Name='" & UCase(minerAddBox.Text) & "']/StartTime")
docFrag.InnerXml = newStartTime
nod2.AppendChild(docFrag)
xmlSearch.Save("Miners.xml")
End Sub
And lastly, the clearAddBox() subroutine
Private Sub clearAddBox()
minerAddBox.Text = ""
End Sub
So, I should point out, that if I rewrite the nodeValidated() Subroutine to something like:
Private Sub nodeValidatedXML()
If playerTypeCBox.SelectedIndex = 0 Then
appendMinerTimeXML()
ElseIf playerTypeCBox.SelectedIndex = 1 Then
appendHaulerTimeXML()
ElseIf playerTypeCBox.SelectedIndex = 2 Then
appendForemanTimeXML()
End If
End Sub
then all of the XML works, except it adds timestamps on names that already exist in the list, which is what i'm trying to avoid. So if I haven't completely pissed you off yet, what is it about the minerValidated() subroutine that is failing to call appendMinerTimeXML()? I feel the problem is either in the minerValidated() sub, or perhaps clearAddBox() is somehow firing and I'm missing it? Thanks for taking the time to slog through this.
Edit: Clarification. The code as I have it right now is failing to append the XML at all. Everything writes fine the first time, but when I remove a name from the list and then re-add, no timestamp is added to the XML.
You need to prevent the user accidentally typing the name twice.(Not sure if you mean adding it twice)
For this I believe you need to clear the minerAddBox.Text in your addminer() if this line is true.
minerListBox.Items.Contains(UCase(minerAddBox.Text)) = True
minerAddBox.Text = ""
Return
Now it will return back to your addplayerXML which will Return to your clearbox(), since you have this in your addplayerXML()
If minerAddBox.Text = "" Then
Return
Now you get to your clearbox() (Which is not really needed now since you cleared the minerAddBox.Text already)
when I remove a name from the list and then re-add, no timestamp is added to the XML.
your minerValidatedXML() is true, because you are not clearing the textbox when you re-add a name to the list box. Or you may need to remove the existing listbox item if it is the same as the textbox
If minerListBox.Items.Contains(UCase(minerAddBox.Text)) = True Then
minerListBox.Items.remove(UCase(minerAddBox.Text))

Trouble with Timer_tick not stopping

I'm very new to programming and vb.net, trying to self teach more so as a hobby, as I have an idea for a program that I would find useful, but I am having trouble getting past this issue and I believe it is to do with the timer.
I have a form of size.(600,600) with one button of size.(450,150) that is set location(100,50) on the form. When clicked I want to move down it's own height, then add a new button in it's place. The code included below works as desired for the first two clicks, but on the third click the button keeps moving and the autoscroll bar extends. I initially thought it was the autoscroll function or the location property, but realised that as the button keeps moving, the timer hasn't stopped. I am aware that the code is probably very clunky in terms of achieving the outcome, and that there are a few lines/variables that are currently skipped over by the compiler (these are from older attempts to figure this out).
I have looked around and can't find the cause of my problem. Any help would be greatly appreciated. Apologies if the code block looks messy - first go.
Public Class frmOpenScreen
Dim intWButtons, intCreateButtonY, intCreateButtonX 'intTimerTick As Integer
Dim arrWNames() As String
Dim ctrlWButtons As Control
Dim blnAddingW As Boolean
Private Sub btnCreateW_Click(sender As System.Object, e As System.EventArgs) Handles btnCreateW.Click
'Creates new Button details including handler
Dim strWName, strWShort As String
Dim intCreateButtonY2 As Integer
Static intNumW As Integer
Dim B As New Button
strWName = InputBox("Please enter the name name of the button you are creating. Please ensure the spelling is correct.", "Create W")
If strWName = "" Then
MsgBox("Nothing Entered.")
Exit Sub
End If
strWShort = strWName.Replace(" ", "")
B.Text = strWName
B.Width = 400
B.Height = 150
B.Font = New System.Drawing.Font("Arial Narrow", 21.75)
B.AutoSizeMode = Windows.Forms.AutoSizeMode.GrowAndShrink
B.Anchor = AnchorStyles.Top
B.Margin = New Windows.Forms.Padding(0, 0, 0, 0)
'Updates Crucial Data (w name array, number of w buttons inc Create New)
If intNumW = 0 Then
ReDim arrWNames(0)
Else
intNumW = UBound(arrWNames) + 1
ReDim Preserve arrWNames(intNumW)
End If
arrWNames(intNumW) = strWShort
intNumW = intNumW + 1
intWButtons = WButtonCount(intWButtons) + 1
'updates form with new button and rearranges existing buttons
intCreateButtonY = btnCreateW.Location.Y
intCreateButtonX = btnCreateW.Location.X
‘intTimerTick = 0
tmrButtonMove.Enabled = True
‘Do While intTimerTick < 16
‘ 'blank to do nothing
‘Loop
'btnCreateW.Location = New Point(intCreateButtonX, intCreateButtonY + 150)
B.Location = New Point(intCreateButtonX, intCreateButtonY)
Me.Controls.Add(B)
B.Name = "btn" & strWShort
intCreateButtonY2 = btnCreateW.Location.Y
If intCreateButtonY2 > Me.Location.Y Then
Me.AutoScroll = False
Me.AutoScroll = True
Else
Me.AutoScroll = False
End If
'MsgBox(intCreateButtonY)
End Sub
Function WButtonCount(ByRef buttoncount As Integer) As Integer
buttoncount = intWButtons
If buttoncount = 0 Then
Return 1
End If
Return buttoncount
End Function
Public Sub tmrButtonMove_Tick(sender As System.Object, e As System.EventArgs) Handles tmrButtonMove.Tick
Dim intTimerTick As Integer
If intTimerTick > 14 Then
intTimerTick = 0
End If
If btnCreateW.Location.Y <= intCreateButtonY + 150 Then
btnCreateW.Top = btnCreateW.Top + 10
End If
intTimerTick += 1
If intTimerTick = 15 Then
tmrButtonMove.Enabled = False
End If
End Sub
End Class
So my current understanding is that the tick event handler should be increasing the timertick variable every time it fires, and that once it has hits 15 it should diable the timer and stop the button moving, but it is not doing so.
Thanks in advance.
IntTimerTick is initialized to 0 at the beginning of every Tick event. This won't happen if you declare it to be static:
Static Dim intTimerTick As Integer