Wait until media element has naturalDuration information - vb.net

I need to make a loop to look at a lot of mp3 files and getting their naturalDuration property using a mediaElement. The problem is that mediaElement need some time to load every single file and .source property works like async process (I think) because I have to click two times on below code if I want to obtain naturalDuration property. First click I have just 00:00:00 value, second clik give me real value.
Private Sub button_Click(sender As Object, e As RoutedEventArgs) Handles button.Click
mediaElement.Source = New Uri("\\Mac\Home\Desktop\NOVEDADES01\AbrahamMateo-OldSchool.mp3")
textBlock.Text = mediaElement.NaturalDuration.ToString
End Sub
If I try to wait after .Source instruction, the application keeps on loop.
Private Sub button_Click(sender As Object, e As RoutedEventArgs) Handles button.Click
mediaElement.Source = New Uri("\\Mac\Home\Desktop\NOVEDADES01\AbrahamMateo-OldSchool.mp3")
Do
Loop Until mediaElement.NaturalDuration.TimeSpan.TotalSeconds > 0
textBlock.Text = mediaElement.NaturalDuration.ToString
End Sub
I also have try set .source through an async process and wait for mediaOpenend event, but it look like mediaElemento can not end until the first click was ending
How could I get real value of naturalDuration inside one single process or function just after set .source property and without playing the file?
Thanks a lot!!

Ok, late and may be not so elegant but this was my solution for getting duration of a mp3 file. I used MusicProperties Class.
Public Function infoMP3(elfichero As String) As String
Dim salida As String = ""
Dim miTask = Task.Run(Async Function() As Task(Of String)
Dim musicFile As StorageFile = Await StorageFile.GetFileFromPathAsync(elfichero)
Dim FileProperties As StorageItemContentProperties = musicFile.Properties
Dim musicFileProperties As MusicProperties = Await FileProperties.GetMusicPropertiesAsync()
Dim tiempo = musicFileProperties.Duration
Dim horas As String
If tiempo.Hours < 10 Then
horas = "0" & tiempo.Hours.ToString
Else
horas = tiempo.Hours.ToString
End If
Dim minutos As String
If tiempo.Minutes < 10 Then
minutos = "0" & tiempo.Minutes.ToString
Else
minutos = tiempo.Minutes.ToString
End If
Dim segundos As String
If tiempo.Seconds < 10 Then
segundos = "0" & tiempo.Seconds.ToString
Else
segundos = tiempo.Seconds.ToString
End If
Dim autor = musicFileProperties.Artist
Dim titulo = musicFileProperties.Title
Dim presalida As String = "[" & horas & ":" & minutos & ":" & segundos & "];[" & titulo & "];[" & autor & "] " & elfichero
Return presalida
End Function)
miTask.Wait()
salida = miTask.Result
Return salida
End Function
To get access to the files later on Windows 10, you have to save permission for the files and/or folders. Do this when you select them.
...
Dim listToken = Windows.Storage.AccessCache.StorageApplicationPermissions.FutureAccessList.Add(rutaS)
...
where rutaS is an SotorageFolder object.

Related

Getting variables form text file, then setting a new variable

I'm creating a code for the computers at work. I had to make an "Install" program. I didn't know how to do it properly but I found a way to do it.
When I "Install" the program on a other computer I have my USB-stick and copy it to the local disk at the computer.
Now I start the program for the first time at their computer and this code run's
and then I got an error here because Program is not yet divined:
Dim lMateriaalCertificaat As String = System.IO.File.ReadAllText(Program & "Materialen&Certificaten.txt")
Dim Pathproj As String = AppDomain.CurrentDomain.BaseDirectory
Dim Pathfile As String = Pathproj.Replace("bin\Debug\", "Bestanden\Locatie.txt")
Dim Program As String = System.IO.File.ReadAllText(Pathfile)
'Deze bestanden worden aangemaakt en er wordt automatisch een route ingezet.
Dim lMateriaalCertificaat As String = System.IO.File.ReadAllText(Program & "Materialen&Certificaten.txt")
Dim lBibliotheek As String = System.IO.File.ReadAllText(Program & "Bibliotheek.txt")
Dim lExcel_autonummering As String = System.IO.File.ReadAllText(Program & "Excelbestand autonummering.txt")
Dim lLocatie_telbestanden As String = System.IO.File.ReadAllText(Program & "Locatie telbestanden.txt")
Dim lMapnamen As String = System.IO.File.ReadAllText(Program & "Mapnamen.txt")
Dim lOrderschijf As String = System.IO.File.ReadAllText(Program & "Zoek schijf.txt")
Because when the form2_load I do this and then I wan't to divine that string.
Public Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim Locatie_05Kuipers As String
If System.IO.File.ReadAllText(Pathfile) = "" Then
'If System.IO.File.ReadAllText("C:\testing1\testing2\testing7\testing1\testing1\text.txt") = "" Then
Locatie_05Kuipers = InputBox("Vul hier de Locatie waar je start bestanden moeten staan. Bijvoorbeeld: K:\Inventor\Instalprogram\ ")
If System.IO.File.Exists(Pathfile) Then
System.IO.File.Delete(Pathfile)
End If
Dim objStreamWriter As StreamWriter
objStreamWriter = New StreamWriter(Pathfile)
objStreamWriter.WriteLine(Locatie_05Kuipers & "\03 - Locaties")
objStreamWriter.Close()
ButtonInstal.Visible = True
Exit Sub
Else
End If
So how or where do I need to put my strings?
You can save a path in your settings, and every time you need it, you can create the file and put your data in it.
For example:
Dim pathString As String = My.Settings.filePath
Dim fullPath = Path.Combine(pathString, "Locatie.txt")
If Not Directory.Exists(pathString) Then
Directory.CreateDirectory(pathString)
File.Create(fullPath)
Else
If Not File.Exists(pathString) Then
File.Create(fullPath)
Else
Console.WriteLine($"File {fullPath}already exists.")
End If
End If

Downloading files code gets unexpected 404 error

My code downloads files in loop but after the last file downloads it keeps downloading files that aren't there. Website shows redirect and 404 error.
I'm new with visual basic so I'm asking for help here.
My.Computer.Network.DownloadFile(strFullUrlDownload, strFullSavePath, False, 1000)
404 error
redirect
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim strMainUrl As String = "http://jixxer.com/123/"
Dim dt As DateTime = DateTime.Now
Dim dtDate As String = dt.ToString("yyyy-MM-dd")
Dim strSlash As String = "/"
Dim strPdf As String = "pdf"
Dim strDot As String = "."
Dim strPage As String = "page"
Dim strPageNbr As String = 1
Dim intCounter As Integer = 1
Dim strPageCounter As String = String.Format("{0:000}", intCounter)
Dim strSavePath As String = "D:\dls\title1\"
Dim strFullSavePath As String = strSavePath & strPageCounter & strDot & strPdf
Dim strFullUrlDownload As String = strMainUrl & dtDate & strSlash & strPdf & strSlash & strPage & strPageNbr & strDot & strPdf
Do Until strPageCounter = 200
' Downloads the resource with the specified URI to a local file.
My.Computer.Network.DownloadFile(strFullUrlDownload, strFullSavePath, False, 1000)
intCounter = intCounter + 1
strPageNbr = strPageNbr + 1
strPageCounter = String.Format("{0:000}", intCounter)
strFullSavePath = strSavePath & strPageCounter & strDot & strPdf
strFullUrlDownload = strMainUrl & dtDate & strSlash & strPdf & strSlash & strPage & strPageNbr & strDot & strPdf
Loop
End Sub
End Class
Try
'TRY to download the file using https first...
My.Computer.Network.DownloadFile(New Uri("https://" & ServerAddress & WebLogoPath & Convert.ToString(RowArray(0)) & ".png"), Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) & "\" & AppDataFolder & PCLogoPath & Convert.ToString(RowArray(0)) & ".png", "", "", False, 500, True)
Catch ex_https As Exception
'Unable to locate file or write file
'If the operation timed out...
If (ex_https.Message = "The operation has timed out") Then
'Re-TRY to download the file using http instead, as a time out error may indicate that HTTPS is not supported.
Try
My.Computer.Network.DownloadFile(New Uri("http://" & ServerAddress & WebLogoPath & Convert.ToString(RowArray(0)) & ".png"), Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) & "\" & AppDataFolder & PCLogoPath & Convert.ToString(RowArray(0)) & ".png", "", "", False, 500, True)
Catch ex_http As Exception
'Most likely, the file doesn't exist on the server. Either way, we cannot obtain the file so we need to perform the same action,
'which is handled outside of this Try block.
End Try
Else
'This is most likely a 404 error. Either way, we cannot obtain the file (and the connection is not timing out) - so
'we need to perform the same action, which is handled outside of this Try block.
End If
End Try
I just put the counter at 200 to test and make sure it works. But I know I need a way to quit on error but not sure how to code it yet. Appreciate any help.
If you don't know how many documents are stored in that remote directory, you have to handle the exception when a page is not found.
It's always possible to receive WebExceptions when a resource is requested from a site, so you should handle this case anyway.
I suggest to use the WebClient class directly instead of Network.DownloadFile(), which may be handy if you want to show a predefined UI of the progress (when it's possible), but using WebClient directly, lets you perform the download asynchrounously if you need it to, using the async/await pattern and the WebClient.DownloadFileTaskAsync() method.
Another suggestion: use a method to download those files, so you can call it from anywhere in your code. You can use a class or a module to store your methods, so you don't clutter your UI and you can also easily reuse these classes or modules in different projects, just including in a project the file that contains them.
Your code could be modified as follow (synchronous version):
You need to pass to the DownloadPdfPages method the remote base address: http://jixxer.com/123, the Path where the files are store (filesPath).
The third and fourth parameters are optional:
- If you don't specify a resourceName, Date.Now.ToString("yyyy-MM-dd") is assumed,
- If you don't specify a startPage, it will default to 1, converted in page1.pdf (the example here asks to start from page 3).
Note: I'm using String Interpolation here: $"page{startPage + pageCount}.pdf".
If your VB.Net version doesn't support it, use String.Format() instead.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim numberOfPages = DownloadPdfPages("http://jixxer.com/123", "D:\dls\title1", "", 3)
If numberOfPages > 0 Then
MessageBox.Show($"Download completed. Number of pages: {numberOfPages}")
Else
MessageBox.Show("Download failed")
End If
End Sub
Private Function DownloadPdfPages(baseAddress As String, filesPath As String, Optional resourceName As String = "", Optional startPage As Integer = 1) As Integer
If String.IsNullOrEmpty(resourceName) Then resourceName = Date.Now.ToString("yyyy-MM-dd")
Dim resourceAddr = Path.Combine(baseAddress, resourceName, "pdf")
Dim pageCount = 0
Dim client = New WebClient()
Try
Do
Dim documentName = $"page{startPage + pageCount}.pdf"
Dim resourceUri = New Uri(Path.Combine(resourceAddr, documentName), UriKind.Absolute)
Dim fileName = Path.Combine(filesPath, documentName)
client.DownloadFile(resourceUri, fileName)
pageCount += 1
Loop
Catch ex As WebException
If ex.Response IsNot Nothing Then
Dim statusCode = DirectCast(ex.Response, HttpWebResponse).StatusCode
If statusCode = HttpStatusCode.NotFound Then
Return pageCount
End If
ElseIf ex.Status = WebExceptionStatus.ProtocolError AndAlso ex.Message.Contains("404") Then
Return pageCount
Else
' Log and/or ...
Throw
End If
Return 0
Finally
client.Dispose()
End Try
End Function
Asynchronous version, using the WebClient.DownloadFileTaskAsync() method.
Just a few changes ae necessary, note the Async keyword added to both the Button.Click handler and the DownloadPdfPagesAsync() method.
The Await keyword is then used to wait for a method to complete, without blocking the UI:
Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim numberOfPages = Await DownloadPdfPagesAsync("http://jixxer.com/123", "D:\dls\title1", "", 3)
If numberOfPages > 0 Then
MessageBox.Show($"Download completed. Number of pages: {numberOfPages}")
Else
MessageBox.Show("Download failed")
End If
End Sub
Private Async Function DownloadPdfPagesAsync(baseAddress As String, filesPath As String, Optional resourceName As String = "", Optional startPage As Integer = 1) As Task(Of Integer)
If String.IsNullOrEmpty(resourceName) Then resourceName = Date.Now.ToString("yyyy-MM-dd")
Dim resourceAddr = Path.Combine(baseAddress, resourceName, "pdf")
Dim pageCount = 0
Dim client = New WebClient()
Try
Do
Dim documentName = $"page{startPage + pageCount}.pdf"
Dim resourceUri = New Uri(Path.Combine(resourceAddr, documentName), UriKind.Absolute)
Dim fileName = Path.Combine(filesPath, documentName)
Await client.DownloadFileTaskAsync(resourceUri, fileName)
pageCount += 1
Loop
Catch ex As WebException
If ex.Response IsNot Nothing Then
Dim statusCode = DirectCast(ex.Response, HttpWebResponse).StatusCode
If statusCode = HttpStatusCode.NotFound Then
Return pageCount
End If
ElseIf ex.Status = WebExceptionStatus.ProtocolError AndAlso ex.Message.Contains("404") Then
Return pageCount
Else
' Log and/or ...
Throw
End If
Return 0
Finally
client.Dispose()
End Try
End Function

Query in VB.net sometimes doesn't work

I have a functionality which saves the information from a webform to the database, which is working fine.
This is my code for save functionality in Onspec.aspx.vb page
Public Sub SaveClick(ByVal sender As Object, ByVal e As System.EventArgs)
If Not Page.IsValid Then
litMessage.Text = ""
Exit Sub
End If
Try
Dim sName As String = ""
With EmployerCandidate
.employerid = Master.Employer.ID
.employeruserid = 0
Try
.CVID = DocId
Catch
End Try
.Name = uxName.Text
.SurName = uxSurname.Text
Try
.PostCode = uxPostcode.Text
Catch ex As Exception
End Try
.Email = uxEmail.Text
Try
.MobileNo = uxMobileNo.Text
Catch ex As Exception
End Try
.OnSpec = True
.OnSpecType = uxOnSpecCategory.SelectedItem.Text
.Source = uxSourceID.SelectedItem.Text
.LastEmployer = uxEmployer.Text
.LastJobTitle = uxJobtitle.Text
.Profile = uxProfile.Text.Trim
End With
' email()
ResetForm()
panForm.Visible = False
panUpload.Visible = True
uxSubmit.Visible = False
uxUpload.Visible = True
litMessage.Text = "Thank you for submitting your details! We'll be in touch when appropriate vacancy arises. <a href='#' onclick='parent.$.colorbox.close()'>Close</a>"
UploadPanel.Visible = False
Response.Redirect("onspec-complete.aspx?e=" & Master.Employer.ID)
Catch ex As Exception
litMessage.Text = Core.Helper.FancyMessage("Error as occurred - " & ex.Message.ToString, "ERROR")
End Try
End Sub
Now, I want to send emails along with saving the data in the database so I added the following lines of code before ResetForm().
Dim specmatch As DataRow = DB.GetRow("SELECT TOP 1 name,email,password FROM [user] usr JOIN employeruser empUsr ON usr.id = empUsr.userid WHERE empUsr.empusertype = 1 AND empUsr.employerid = #eid ", DB.SIP("eid", LocalHelper.UserEmployerID))
If my query returns a value then I want to send email by calling the email function.
If specmatch IsNot Nothing Then
email()
End If
But in this line of code the employerid value is sometimes empty. It can't pick the id therefore it is returning an empty row. And therefore it's not calling the email function.
This id is the same as
.employerid = Master.Employer.ID
But if I replace the LocalHelper.UserEmployerID with Master.Employer.ID the form gives an error:
Object reference not set to an instance of an object.
employerid is an integer value.
I have also tried to add the following lines of code in this page(Onspec.aspx.vb)
Public ReadOnly Property EmployerId() As Integer
Get
Return Master.Employer.ID
End Get
End Property
But I get the same error:
Object reference not set to an instance of an object.
The above lines of code does not make any difference.
So I replaced Master.Employer.ID with LocalHelper.UserEmployerID
Where in localhelper.vb file (under appcode folder) it is determining employerid from the website with following lines of code.
Public Shared Function UserEmployerID() As Integer
If HttpContext.Current.Items("lh_useremployerid") Is Nothing Then
If LocalHelper.UserTypeCode = "e" Then
HttpContext.Current.Items("lh_useremployerid") = Core.DB.GetInteger("SELECT employerid FROM employeruser WHERE userid = " & LocalHelper.UserID)
Else
HttpContext.Current.Items("lh_useremployerid") = 0
End If
End If
Return HttpContext.Current.Items("lh_useremployerid")
End Function
These lines of code has been used in many places and works perfectly fine. In this case as well, it was working fine last Friday and now it's not. There was no changes made.
This is my email function
Private Sub email()
Dim strCandidateName As String = uxName.Text.Trim & " " & uxSurname.Text.Trim
Dim strCandidateSurname As String = uxSurname.Text
Dim strCandidateEmail As String = uxEmail.Text.Trim
Dim strCandidatePhone As String = uxMobileNo.Text.Trim
Dim strCPass As String = "mpb123"
Dim strContactType As String = "Speculative Application has been submited on the category of " & uxOnSpecCategory.SelectedItem.Text
Dim strContactMessage As String = uxProfile.Text.Trim
'''''''''''''''''''variable
Dim qq As String = String.Format("Select top 1 name, email, password FROM [user] WHERE id in (Select userid FROM employeruser WHERE empusertype=1 and employerid= " & LocalHelper.UserEmployerID & ")")
Dim drow As DataRow = Core.DB.GetRow(qq)
Dim semail As String = drow.Item("email").ToString
Dim sname As String = drow.Item("name").ToString
Dim spass As String = drow.Item("password").ToString
'''''''''''''''''''variable
Dim Email As Core.Email
'New Onspec Candidate Email sent to EmployerUser who is assigned to receive onspec email
Email = New Core.Email
With Email
.ContentID = 99
.Replacement("ContactName", strCandidateName)
.Replacement("ContactEmail", strCandidateEmail)
.Replacement("ContactTelephone", strCandidatePhone)
.Replacement("ContactType", strContactType)
.Replacement("ContactMessage", strContactMessage)
.Replacement("AdminContactName", sname)
.Replacement("AdminContactEmail", semail)
.Replacement("SiteName", LocalHelper.AppSetting("sitename"))
Dim attachments As New Generic.List(Of String)
If EmployerCandidate.CVID > 0 Then
Dim doc As New Document(EmployerCandidate.CVID)
attachments.Add(doc.PathOnDisc)
End If
.Attachments = Join(attachments.ToArray(), ";")
.Send()
End With
End Sub
GetRow function is defined in my database.vb page like following which is also used in many other places.
Shared Function GetRow(ByVal selectQueryText As String, ByVal ParamArray params As SqlParameter()) As DataRow
Return GetRowFromDB(selectQueryText, CommandType.Text, params)
End Function
And
Shared Function GetRowFromDB(ByVal selectCommandText As String, ByVal selectCommandType As CommandType, ByVal ParamArray params As SqlParameter()) As DataRow
Dim conn As SqlConnection = Nothing
Try
conn = GetOpenSqlConnection()
Return GetRowFromDB(conn, selectCommandText, selectCommandType, params)
Finally
If conn IsNot Nothing Then conn.Dispose()
End Try
End Function
Please suggest ways on how I can organize my code so that it works all the time.

Visual Basic - system.nullReferenceException

So I'm still a bit of a newbie when it comes to programming, hence why I'm using visual basic. I'm getting this exception raised repeatedly, but the variables that vb is saying have unassigned values have been given values in my code. Can anyone point out where I'm going wrong with this?
EDIT: just a few more details: the file exists, I can read from it using just the ReadLine method, but I need to split the fields so I can compare the scores and get the highest 2 scores
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Dim srdFile As System.IO.StreamReader
Dim strLine As String
Dim strField(1) As String
Dim strName() As String
Dim strScore() As String
Dim i = 0
srdFile = New System.IO.StreamReader("HighScores.dat")
rtbOut.AppendText("HighScores:" & vbNewLine & vbNewLine)
Do Until srdFile.Peek() = -1
strLine = srdFile.ReadLine()
strField = strLine.Split(",")
strName(i) = strField(0)
strScore(i) = strField(1)
rtbOut.AppendText(strName(i) & ", " & strScore(i) & vbNewLine)
i = i + 1
Loop
End Sub
Following two arrays are never initialized: strName and strScore
I don't know the logic, but one way would be to use a List(Of String) instead which does not need to get the correct size in the first place and can be resized. I would also use the Using-statement to dispose the stream properly:
Using srdFile As New System.IO.StreamReader("HighScores.dat")
Dim strLine As String
Dim strField(1) As String
Dim strName As New List(Of String)
Dim strScore As New List(Of String)
Dim i = 0
rtbOut.AppendText("HighScores:" & vbNewLine & vbNewLine)
Do Until srdFile.Peek() = -1
strLine = srdFile.ReadLine()
strField = strLine.Split(","c)
strName.Add(strField(0))
strScore.Add(strField(1))
rtbOut.AppendText(strName(i) & ", " & strScore(i) & vbNewLine)
i += 1
Loop
End Using
Side-note: i recommend to set Option Strict to On by default.
By the way, here is a completely different approach doing the same but with LINQ:
Dim lines = From line In IO.File.ReadLines("HighScores.dat")
Where Not String.IsNullOrWhiteSpace(line)
Let fields = line.Split(","c)
Let name = fields.First()
Let score = fields.Last()
Select String.Format("{0}, {1}", name, score)
rtbOut.Text = String.Join(Environment.NewLine, lines)
I find this more readable.
Before you use an array, you need to assign a fixed array size in the computer memory locations. You can do this by initialising an array with the number of array elements. In your code, you have not allocated any memory to strName() and strScore() before using them, hence the code will throw an exception.
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim srdFile As System.IO.StreamReader
Dim strLine As String
Dim strField(1) As String
Dim strName(10) As String ''fixed size array (Using List(Of T) is a better option)
Dim strScore(10) As String ''fixed size array (Using List(Of T) is a better option)
Dim i = 0
srdFile = New System.IO.StreamReader("HighScores.dat")
rtbOut.AppendText("HighScores:" & vbNewLine & vbNewLine)
Do Until srdFile.Peek() = -1
strLine = srdFile.ReadLine()
strField = strLine.Split(",")
strName(i) = strField(0)
strScore(i) = strField(1)
rtbOut.AppendText(strName(i) & ", " & strScore(i) & vbNewLine)
i = i + 1
Loop
End Sub
You can also create a dynamic array. Please follow Resizing an array at runtime in VB.NET on Stackoverflow about dynamic array.

How to replace multiple consective lines in a line and skip the header for that section

I need to find a section header, in this case "[Store Hours]", in a text file that I'm using to save the settings for the program. I need to skip the header and replace the next 7 lines with the text that is in the text boxes. The code below currently deletes the header "[Store Hours]" and does not replace any of the lines.
Dim objFileName As String = "Settings.txt"
Private Sub BtnAdd_Click(sender As System.Object, e As System.EventArgs) Handles btnSaveHours.Click
Dim OutPutLine As New List(Of String)()
Dim matchFound As Boolean
For Each line As String In System.IO.File.ReadAllLines(objFileName)
matchFound = line.Contains("[Store Hours]")
If matchFound Then
'does not skip the header line
line.Skip(line.Length)
'Need to loop through this 7 times (for each day of the week)
'without reading the header again
For intCount = 0 To 6
Dim aryLabelDay() As String = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}
Dim varLabelNameIn As String = "txt" & aryLabelDay(intCount).ToString & "In"
Dim varDropNameIn As String = "drp" & aryLabelDay(intCount).ToString & "In"
Dim varLabelNameOut As String = "txt" & aryLabelDay(intCount).ToString & "Out"
Dim varDropNameOut As String = "drp" & aryLabelDay(intCount).ToString & "Out"
Dim varTextBoxInControl() As Control = Me.Controls.Find(varLabelNameIn, True)
Dim varDropBoxInControl() As Control = Me.Controls.Find(varDropNameIn, True)
Dim varTextBoxOutControl() As Control = Me.Controls.Find(varLabelNameOut, True)
Dim varDropBoxOutControl() As Control = Me.Controls.Find(varDropNameOut, True)
Dim dymTextNameIn As TextBox = DirectCast(varTextBoxInControl(0), TextBox)
Dim dymDropNameIn As ComboBox = DirectCast(varDropBoxInControl(0), ComboBox)
Dim dymTextNameOut As TextBox = DirectCast(varTextBoxOutControl(0), TextBox)
Dim dymDropNameOut As ComboBox = DirectCast(varDropBoxOutControl(0), ComboBox)
Dim ReplaceLine As String
ReplaceLine = dymTextNameIn.Text & "," & dymDropNameIn.Text & "," & dymTextNameOut.Text & "," & dymDropNameOut.Text
'this doesn't replace anything
line.Replace(line, ReplaceLine)
intCount += 1
Next intCount
Else
OutPutLine.Add(line)
End If
Next
End Sub
Instead of using ReadAllLines simply use a streamreader and read the file line by line, like this;
Dim line As String
Using reader As StreamReader = New StreamReader("file.txt")
' Read one line from file
line = reader.ReadLine
If(line.Contains("[Store Hours]") Then
'The current line is the store hours header, so we skip it (read the next line)
line = reader.ReadLine
'Process the line like you want, and keep processing through the lines by doing a readline each time you want to progress to the next line.
End If
End Using
More importantly though, you should not be saving the settings for your program in a text file. They should be stored in app.config or web.config. See this question for further guidance on that.
Part of your confusion might be coming from the fact that you can't just replace part of a text file without copying it and overwriting it. One way, to do this, is to copy the file to memory changing the appropriate lines and overwriting the existing file with the new information. Here's one way that can be done:
Private Sub BtnAdd_Click(sender As System.Object, e As System.EventArgs) Handles btnSaveHours.Click
Dim OutPutLine As New List(Of String)()
Dim sr As New StreamReader(objFileName)
While Not sr.EndOfStream
Dim line = sr.ReadLine
'Found the header so let's save that line to memory and add all the other _
info after it.
If line.Contains("[Store Hours]") Then
OutPutLine.Add(line)
'Need to loop through this 7 times (for each day of the week)
'without reading the header again
Dim aryLabelDay() As String = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}
For intCount = 0 To 6
'even though we're not using the info from the file, calling _
Readline advances the file pointer so that the next iteration _
of the while loop we can finish reading the file.
If Not sr.EndOfStream Then
line = sr.ReadLine
Dim dymTextNameIn As TextBox = DirectCast(Me.Controls("txt" & aryLabelDay(intCount) & "In"), TextBox)
Dim dymDropNameIn As ComboBox = DirectCast(Me.Controls("drp" & aryLabelDay(intCount) & "In"), ComboBox)
Dim dymTextNameOut As TextBox = DirectCast(Me.Controls("txt" & aryLabelDay(intCount) & "Out"), TextBox)
Dim dymDropNameOut As ComboBox = DirectCast(Me.Controls("drp" & aryLabelDay(intCount) & "Out"), ComboBox)
OutPutLine.Add(dymTextNameIn.Text & "," & dymDropNameIn.Text & "," & dymTextNameOut.Text & "," & dymDropNameOut.Text)
End If
Next
Else
'Any line that isn't in that section gets copied as is.
OutPutLine.Add(line)
End If
End While
'Copy all the new info to the same file overwriting the old info.
File.WriteAllLines(objFileName, OutPutLine)
End Sub
On a side note. The Controls collection is indexed by number or name which makes it fairly simple to access the appropriate control just by knowing its name.
Thanks for the help I actually figured it out and this is the final code I used
Private Sub btnSaveHours_Click(sender As System.Object, e As System.EventArgs) Handles btnSaveHours.Click
Dim intOutPutLine As New List(Of String)()
Dim blnSearchString As Boolean
Dim intLineCount As Integer = -1
Dim intLoopCount As Integer
For Each line As String In System.IO.File.ReadAllLines(objFileName)
blnSearchString = line.Contains("[Store Hours]")
If blnSearchString Then
intLineCount = intOutPutLine.Count
line.Remove(0)
intLoopCount = 0
ElseIf intLineCount = intOutPutLine.Count And intLoopCount < 7 Then
line.Length.ToString()
line.Remove(0)
intLoopCount += 1
Else
intOutPutLine.Add(line)
End If
Next
System.IO.File.WriteAllLines(objFileName, intOutPutLine.ToArray())
Dim objFileWrite As New StreamWriter(objFileName, True)
If File.Exists(objFileName) Then
objFileWrite.WriteLine("[Store Hours]")
Dim varMe As Control = Me
Call subConvertFrom12to24Hours(objFileWrite, varMe)
Else
objFileWrite.WriteLine("[Store Hours]")
Dim varMe As Control = Me
Call subConvertFrom12to24Hours(objFileWrite, varMe)
End If
Call btnClear_Click(sender, e)
End Sub