Print multiple pages with Foreach (e.HasMorepages) - vb.net

I have a question and i hope somebody can help me.
I would like to print a page, but if the page is longer than the first page than i would like to print multiple pages.
I've seen many code examples using e.HasMorePages.
UPDATE
This is my current code, it shows a second page but it's blank.
If it would be great if somebody can help me with this.
Private Sub PrintDocument_BO_PrintPage(sender As Object, e As Printing.PrintPageEventArgs) Handles PrintDocument_BO.PrintPage
Static page As Integer = 1
Dim startPosition As Integer = (page - 1) * PrintDocument_BO.DefaultPageSettings.Bounds.Height
Static maxPages As Integer = 0
If page = 1 Then
For Each ctrl1 As Control In PrintBackorder.PrintBO_panel.Controls
If TypeOf ctrl1 Is TextBox Or TypeOf ctrl1 Is Label Or TypeOf ctrl1 Is PictureBox Then
ctrl1.Tag = Int((ctrl1.Top + ctrl1.Height) / PrintDocument_BO.DefaultPageSettings.Bounds.Height) + 1
If CInt(ctrl1.Tag) > maxPages Then maxPages = CInt(ctrl1.Tag)
End If
Next
For Each ctrl2 As Control In PrintBackorder.BOLayoutPanel.Controls
If TypeOf ctrl2 Is TextBox Or TypeOf ctrl2 Is Label Or TypeOf ctrl2 Is PictureBox Then
ctrl2.Tag = Int((ctrl2.Top + ctrl2.Height) / PrintDocument_BO.DefaultPageSettings.Bounds.Height) + 1
If CInt(ctrl2.Tag) > maxPages Then maxPages = CInt(ctrl2.Tag)
End If
Next
End If
Dim sf = New StringFormat()
For Each ctrl1 As Control In PrintBackorder.PrintBO_panel.Controls
If CInt(ctrl1.Tag) = page Then
If TypeOf ctrl1 Is TextBox Or TypeOf ctrl1 Is Label Then
e.Graphics.DrawString(ctrl1.Text, ctrl1.Font, Brushes.Black, ctrl1.Bounds.Location)
ElseIf TypeOf ctrl1 Is PictureBox Then
'e.Graphics.DrawImage(DirectCast(ctrl, PictureBox).Image, New PointF(ctrl.Left, ctrl.Top - startPosition))
Dim myBitmap1 = New Bitmap(PrintBackorder.picBarcode.Width, PrintBackorder.picBarcode.Height - 5)
'Dim myBitmap1 As Bitmap = New Bitmap(PrintBackorder.picBarcode.Width, PrintBackorder.picBarcode.Height)
PrintBackorder.picBarcode.DrawToBitmap(myBitmap1, New Rectangle(0, 0, PrintBackorder.picBarcode.Width, PrintBackorder.picBarcode.Height))
e.Graphics.InterpolationMode = Drawing.Drawing2D.InterpolationMode.HighQualityBicubic
e.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality
'e.Graphics.SmoothingMode = Drawing.Drawing2D.SmoothingMode.HighQuality
e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor
e.Graphics.CompositingQuality = Drawing.Drawing2D.CompositingQuality.HighQuality
e.Graphics.DrawImage(myBitmap1, 625, 50)
End If
End If
Next
For Each ctrl2 As Control In PrintBackorder.BOLayoutPanel.Controls 'PrintBackorder.PrintBO_panel.Controls
If CInt(ctrl2.Tag) = page Then
If TypeOf ctrl2 Is TextBox Or TypeOf ctrl2 Is Label Then
sf.Alignment = If(PrintBackorder.BOLayoutPanel.GetColumn(ctrl2) < 2, StringAlignment.Near, StringAlignment.Far)
e.Graphics.DrawString(ctrl2.Text, ctrl2.Font, Brushes.Black, PrintBackorder.PrintBO_panel.PointToClient(PrintBackorder.BOLayoutPanel.PointToScreen(ctrl2.Bounds.Location)), sf)
End If
End If
Next
page += 1
If page > maxPages Then
e.HasMorePages = False
page = 1
maxPages = 0
MsgBox("done")
Else
e.HasMorePages = True
End If
End Sub
I know i shouldn't use a For Each loop but i don't know how to use a While loop in this case.

Here is a general example of the principle provided in the comments:
'The data to be printed.
Private records As New List(Of String)
'The index of the next record to be printed.
Private recordIndex As Integer
Private Sub Button1_Click(...) Handles Button1.Click
'Start printing from the first record.
recordIndex = 0
PrintDocument1.Print()
End Sub
Private PrintDocument1_PrintPage(...) Handles PrintDocument1.PrintPage
Dim startRecordIndex = recordIndex
'Print 10 records or, if there are not 10 records left, to the end of the list.
Dim endRecordIndex = Math.Min(recordIndex + 9, records.Count - 1)
For startRecordIndex To endRecordIndex
Dim record = records(recordIndex)
e.Graphics.DrawString(record, ...)
Next
'The next page will start at the next unprinted record if there is one.
recordIndex = endRecordIndex + 1
e.HasMorePages = recordIndex < records.Count
End Sub

Related

Print scrollable panel which more than two or more pages containing pictureboxes , lables and textboxes using vb.net

hello folks trying to print a scrollable panel containing labels, text boxes and picture boxes and list views which is probably more than two pages. I have tried and search for help online, i can get labels and text boxes printed, how do i make list view to be printed.
Static page As Integer = 1
Dim startPosition As Integer = (page - 1) * PrintDocument1.DefaultPageSettings.Bounds.Height
Static maxPages As Integer = 0
If page = 1 Then
For Each ctrl As Control In Me.Panel1.Controls
If TypeOf ctrl Is TextBox Or TypeOf ctrl Is Label Or TypeOf ctrl Is PictureBox Then
ctrl.Tag = Int((ctrl.Top + ctrl.Height) / PrintDocument1.DefaultPageSettings.Bounds.Height) + 1
If CInt(ctrl.Tag) > maxPages Then maxPages = CInt(ctrl.Tag)
End If
Next
End If
For Each ctrl As Control In Me.Panel1.Controls
If CInt(ctrl.Tag) = page Then
If TypeOf ctrl Is TextBox Or TypeOf ctrl Is Label Then
Dim sf As New System.Drawing.StringFormat
If TypeOf ctrl Is TextBox Then
If DirectCast(ctrl, TextBox).TextAlign = HorizontalAlignment.Right Then
sf.Alignment = StringAlignment.Far
Else
sf.Alignment = StringAlignment.Near
End If
ElseIf TypeOf ctrl Is Label Then
If DirectCast(ctrl, Label).TextAlign = ContentAlignment.TopLeft Then
sf.Alignment = StringAlignment.Near
ElseIf DirectCast(ctrl, Label).TextAlign = ContentAlignment.TopRight Then
sf.Alignment = StringAlignment.Far
End If
End If
sf.FormatFlags = StringFormatFlags.NoClip
e.Graphics.DrawString(ctrl.Text, ctrl.Font, New SolidBrush(ctrl.ForeColor), New RectangleF(ctrl.Left, ctrl.Top - startPosition, ctrl.Width + 50, ctrl.Height), sf)
ElseIf TypeOf ctrl Is PictureBox Then
If Not DirectCast(ctrl, PictureBox).image is nothing Then
e.Graphics.DrawImage(DirectCast(ctrl, PictureBox).Image, New PointF(ctrl.Left, ctrl.Top - startPosition))
End If
End If
End If
Next
page += 1
If page > maxPages Then
e.HasMorePages = False
page = 1
maxPages = 0
Else
e.HasMorePages = True
End If
Since the listview on the panel is not scrollable i was advice to capture it as image by adding some few code to the existing one.
Static page As Integer = 1
Dim startPosition As Integer = (page - 1) * PrintDocument1.DefaultPageSettings.Bounds.Height
Static maxPages As Integer = 0
If page = 1 Then
For Each ctrl As Control In Me.Panel1.Controls
If TypeOf ctrl Is TextBox Or TypeOf ctrl Is Label Or TypeOf ctrl Is PictureBox Or TypeOf ctrl is ListView Then
ctrl.Tag = Int((ctrl.Top + ctrl.Height) / PrintDocument1.DefaultPageSettings.Bounds.Height) + 1
If CInt(ctrl.Tag) > maxPages Then maxPages = CInt(ctrl.Tag)
End If
Next
End If
For Each ctrl As Control In Me.Panel1.Controls
If CInt(ctrl.Tag) = page Then
If TypeOf ctrl Is TextBox Or TypeOf ctrl Is Label Then
Dim sf As New System.Drawing.StringFormat
If TypeOf ctrl Is TextBox Then
If DirectCast(ctrl, TextBox).TextAlign = HorizontalAlignment.Right Then
sf.Alignment = StringAlignment.Far
Else
sf.Alignment = StringAlignment.Near
End If
ElseIf TypeOf ctrl Is Label Then
If DirectCast(ctrl, Label).TextAlign = ContentAlignment.TopLeft Then
sf.Alignment = StringAlignment.Near
ElseIf DirectCast(ctrl, Label).TextAlign = ContentAlignment.TopRight Then
sf.Alignment = StringAlignment.Far
End If
End If
sf.FormatFlags = StringFormatFlags.NoClip
e.Graphics.DrawString(ctrl.Text, ctrl.Font, New SolidBrush(ctrl.ForeColor), New RectangleF(ctrl.Left, ctrl.Top - startPosition, ctrl.Width + 50, ctrl.Height), sf)
ElseIf TypeOf ctrl Is ListView Then
Dim lv As ListView = DirectCast(ctrl, ListView)
Dim img As New Bitmap(lv.Width, lv.Height)
lv.DrawToBitmap(img, New Rectangle(Point.Empty, img.Size))
e.Graphics.DrawImage(img, New PointF(ctrl.Left, ctrl.Top - startPosition))
End If
End If
Next
page += 1
If page > maxPages Then
e.HasMorePages = False
page = 1
maxPages = 0
Else
e.HasMorePages = True
End If

What has to be done to show a marquee output with a scroll menu?

Today i continue my work, Building a menu with a vb.net console application. I found more samples to build with Windows forms. Still i try to get Basic Knowledge with the console surface.I was not able to put the following marquee text in a scroll menu, the second Code past the marquee text.
Module Module1
Dim aTimer As New System.Timers.Timer
Const marqueeText As String = "The quick brown fox... "
Dim sb As New System.Text.StringBuilder
Dim direction As Boolean = False
Sub Main()
aTimer.AutoReset = True
aTimer.Interval = 100 '1/10 second
AddHandler aTimer.Elapsed, AddressOf tick
aTimer.Start()
Console.ReadKey()
End Sub
Private Sub tick(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs)
Console.Clear()
If sb.Length = 0 Then sb.Append(marqueeText)
If direction Then
sb.Insert(0, sb(sb.Length - 1))
sb.Remove(sb.Length - 1, 1)
Else
sb.Append(sb(0))
sb.Remove(0, 1)
End If
Console.CursorLeft = 10 'no visible change
Console.CursorTop = 10 'visible change
Console.Write("{0}{1}", vbCr, sb.ToString)
End Sub
End Module
The marquee text Output from above is not easy to manage with the console.cursorleft command. I have no clue how to move it to the right or to put the marquee Output in the following Code, a scroll menu, on the third line.
Module Module1
Dim MenuList As New List(Of String)
Sub PrintMenu(highlight As Integer, left As Integer, top As Integer)
Dim Nickvektor() As Integer = {1, 2, 3, 4, 5}
For I = 0 To MenuList.Count - 1
Console.CursorLeft = left
Console.CursorTop = top + I
If I = highlight Then
Console.Write("{0}", "[" & Nickvektor(I) & "]")
Else
Console.Write(MenuList(I))
End If
Next
End Sub
Sub Main()
Console.CursorVisible = False
Dim x As Integer = 0
Dim Nickvektor() As String = {" "}
For counter As Integer = 0 To 0
Do
For Each s In Nickvektor
MenuList.Add(s)
Next
x += 1
Loop Until x = 5
Next
Console.SetCursorPosition(10, 16)
Console.Write("[ ]")
Dim CurrentItem As Integer = 0
Dim CurrentKey As ConsoleKey
While CurrentKey <> ConsoleKey.Enter
PrintMenu(CurrentItem, 10, 10)
CurrentKey = Console.ReadKey(True).Key
Select Case CurrentKey
Case ConsoleKey.DownArrow
CurrentItem += 1
Case ConsoleKey.UpArrow
CurrentItem -= 1
End Select
CurrentItem = (CurrentItem + MenuList.Count) Mod MenuList.Count
End While
End Sub
End Module
The menu Frame for the above Code can be used with the up and down arrows on the Keyboard.
Maybe it is to much work but i have no clue how to continue.
The first Solution for the marquee Output is an easy change of the original code. The wrap, vbCr, was the main Problem to move the text output toward the right edge oft he screen. The following code can be used to change the cursorTop Positon and also the cursorLeft Position of the Text.
Console.CursorVisible = False
Console.CursorLeft = 30
Console.CursorTop = 10
Console.Write("{0}", sb.ToString)
The heavy part are the Menu code Lines. To answer my own question some additional help was necessary.
I posted my question on the MS developer Network written in german language. With the following link it can be viewed.
For the case the link should be broken or other cases i post the code on this site.
Module Module1
Dim MenuList As New List(Of String)
Dim aTimer As New System.Timers.Timer
Const marqueeText As String = "The quick brown fox... "
Dim sb As New System.Text.StringBuilder
Dim direction As Boolean = False
Sub PrintMenu(highlight As Integer, left As Integer, top As Integer)
Dim Nickvektor() As Integer = {1, 2, 3, 4, 5}
For I = 0 To MenuList.Count - 1
Console.CursorLeft = left
Console.CursorTop = top + I
If I = highlight Then
Console.Write("{0}", "[" & Nickvektor(I) & "]")
Else
Console.Write(MenuList(I))
End If
Next
End Sub
Sub Main()
Console.CursorVisible = False
aTimer.AutoReset = True
aTimer.Interval = 100 '1/10 second
AddHandler aTimer.Elapsed, AddressOf tick
Dim x As Integer = 0
Dim Nickvektor() As String = {" "}
For counter As Integer = 0 To 0
Do
For Each s In Nickvektor
MenuList.Add(s)
Next
x += 1
Loop Until x = 5
Next
Console.SetCursorPosition(10, 16)
Console.Write("[ ]")
Dim CurrentItem As Integer = 0
Dim CurrentKey As ConsoleKey
While CurrentKey <> ConsoleKey.Enter
If CurrentItem = 2 Then ' Zero can be used to show the marquee output prompt
aTimer.Start() ' With a change to two or four the timer can be stoped:
'Else
'If aTimer.Enabled Then
' aTimer.Stop()
'End If
End If
PrintMenu(CurrentItem, 10, 10)
CurrentKey = Console.ReadKey(True).Key
Select Case CurrentKey
Case ConsoleKey.DownArrow
CurrentItem += 1
Case ConsoleKey.UpArrow
CurrentItem -= 1
End Select
CurrentItem = (CurrentItem + MenuList.Count) Mod MenuList.Count
End While
End Sub
Private Sub tick(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs)
If sb.Length = 0 Then sb.Append(marqueeText)
If direction Then
sb.Insert(0, sb(sb.Length - 1))
sb.Remove(sb.Length - 1, 1)
Else
sb.Append(sb(0))
sb.Remove(0, 1)
End If
Console.CursorVisible = False
Console.CursorLeft = 20
Console.CursorTop = 12 ' For the first Element CursorTop=10, fort he third 12
Console.Write("{0}", sb.ToString)
End Sub
End Module
To learn an other language like English i have to search a lot. Visual Basic Code is mostly written with English key words for the commands. I think it is easier to look up the maintainable changes for your self. To search is not every day funny.

Change color of only part of text inside a DataGridView cell

I have a DGV with 3 columns and each columns contains some text i want to change the fore color of particular words in each columns.
In column1 a word contains _ should be in green color, a word contains +should be in Red color,
for column2 if a word contain - it should be in purple color,
for column3 if a word contains _ the fore color should be Blue.
VB.NET datagridview windows form
Modified from Microsoft help article
Imports System.Data
Public Class Form1
Dim mdtbColourMap As DataTable = Nothing
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'----Following should be replaced with your data access
With DataGridView1
.Columns.Add("Column1", "Column1")
.Columns.Add("Column2", "Column2")
.Columns.Add("Column3", "Column3")
.Rows.Add("Welcome to_ the", "Wonderful-", "World of computing_")
.Rows.Add("This_ is what+ I", "Want-", "In My_ laptop")
.Rows.Add("X_is always+", "Greater-", "Than_ y")
.Columns(0).Width = 120
.Columns(1).Width = 120
.Columns(2).Width = 120
End With
'----Above should be replaced with your data access
'Define the search terms and color for each
mdtbColourMap = New DataTable
mdtbColourMap.Columns.Add(New DataColumn("SearchTerm", GetType(String)))
mdtbColourMap.Columns.Add(New DataColumn("TextColor", GetType(Brush)))
mdtbColourMap.Rows.Add("_", Drawing.Brushes.Green)
mdtbColourMap.Rows.Add("+", Drawing.Brushes.Red)
mdtbColourMap.Rows.Add("-", Drawing.Brushes.Purple)
End Sub
Private Sub DataGridView1_CellPainting(sender As Object, e As DataGridViewCellPaintingEventArgs) Handles DataGridView1.CellPainting
If e.ColumnIndex >= 0 And e.RowIndex >= 0 Then
Dim newRect As New Rectangle(e.CellBounds.X + 1, e.CellBounds.Y + 1, _
e.CellBounds.Width - 4, e.CellBounds.Height - 4)
Dim backColorBrush As New SolidBrush(e.CellStyle.BackColor)
Dim gridBrush As New SolidBrush(Me.DataGridView1.GridColor)
Dim gridLinePen As New Pen(gridBrush)
Try
' Erase the cell.
e.Graphics.FillRectangle(backColorBrush, e.CellBounds)
' Draw the grid lines (only the right and bottom lines;
' DataGridView takes care of the others).
e.Graphics.DrawLine(gridLinePen, e.CellBounds.Left, _
e.CellBounds.Bottom - 1, e.CellBounds.Right - 1, _
e.CellBounds.Bottom - 1)
e.Graphics.DrawLine(gridLinePen, e.CellBounds.Right - 1, _
e.CellBounds.Top, e.CellBounds.Right - 1, _
e.CellBounds.Bottom)
' Draw the inset highlight box.
e.Graphics.DrawRectangle(Pens.Blue, newRect)
' Draw the text content of the cell, ignoring alignment.
If (e.Value IsNot Nothing) Then
Dim strValue As String = CStr(e.Value)
Dim strWords() As String = Split(strValue, " ")
Dim strAlignment As String = "LEFT"
If e.ColumnIndex = 0 Then strAlignment = "RIGHT"
Dim sngX As Integer
If strAlignment = "LEFT" Then
sngX = e.CellBounds.X + 2
Else
sngX = e.CellBounds.Right - 4 - e.Graphics.MeasureString(strValue, e.CellStyle.Font).Width
End If
For i As Integer = 0 To strWords.GetUpperBound(0)
Dim brsTextColor As Drawing.Brush = Nothing
For j As Integer = 0 To mdtbColourMap.Rows.Count - 1
Dim strSearchTerm As String = mdtbColourMap.Rows(j).Item("SearchTerm").ToString
If InStr(strWords(i), strSearchTerm) > 0 Then
brsTextColor = DirectCast(mdtbColourMap.Rows(j).Item("TextColor"), Drawing.Brush) 'change the color
Exit For
End If
Next j
If brsTextColor Is Nothing Then
brsTextColor = Brushes.Black 'default
End If
e.Graphics.DrawString(strWords(i), e.CellStyle.Font, brsTextColor, sngX, e.CellBounds.Y + 2, StringFormat.GenericDefault)
sngX += e.Graphics.MeasureString(strWords(i), e.CellStyle.Font).Width
Next i
End If
e.Handled = True
Finally
gridLinePen.Dispose()
gridBrush.Dispose()
backColorBrush.Dispose()
End Try
End If
End Sub
End Class

Adding checkbox to datagridview column header, not aligning properly

Im trying to add a checkbox to a specific datagridview column header, I found some code online to help but it's not aligning properly and I'm not really sure how to fix it.
Below is an image of the problem and the code, any help would be greatly appreciated!
P.S. I think it might be something to do with properties but I've played around with them but not been successful.
Private checkboxHeader231 As CheckBox
Private Sub show_chkBox()
Dim rect As Rectangle = DataGridView1.GetCellDisplayRectangle(columnIndexOfCheckBox, -1, True)
' set checkbox header to center of header cell. +1 pixel to position
rect.Y = 3
rect.X = rect.Location.X + 8 + (rect.Width / 4)
checkboxHeader231 = New CheckBox()
With checkboxHeader231
.BackColor = Color.Transparent
End With
checkboxHeader231.Name = "checkboxHeader1"
checkboxHeader231.Size = New Size(18, 18)
checkboxHeader231.Location = rect.Location
AddHandler checkboxHeader231.CheckedChanged, AddressOf checkboxHeader231_CheckedChanged
DataGridView1.Controls.Add(checkboxHeader231)
End Sub
Private Sub checkboxHeader231_CheckedChanged(sender As System.Object, e As System.EventArgs)
Dim headerBox As CheckBox = DirectCast(DataGridView1.Controls.Find("checkboxHeader1", True)(0), CheckBox)
For Each row As DataGridViewRow In DataGridView1.Rows
row.Cells(columnIndexOfCheckBox).Value = headerBox.Checked
Next
End Sub
This is my first entry, but I think this is what youre looking for. I tested it and it worked on my datagrid. You were using the width for the rectangle, youll need it for the column width instead. I set the column header to 4, but you would replace the 4 with your column you want to use I put it in two ways, one with a four loop, the other just as single lines. Tell me if this worked for you:
Dim rect As Rectangle = DataGridView1.GetCellDisplayRectangle(4, -1, True) ' replace 4
rect.Y = 3
Dim sum = DataGridView1.Columns(0).Width
'for this area write a for loop to find the width of each column except for the last line which you manually do
'
'
'For i As Integer = 1 To 4 - 1 Step 1 ' replace 4
'sum = sum + DataGridView1.Columns(i).Width
'Next
sum = sum + DataGridView1.Columns(1).Width
sum = sum + DataGridView1.Columns(2).Width
sum = sum + DataGridView1.Columns(3).Width
' stop here and add the last line by hand here
sum = sum + (DataGridView1.Columns(4).Width / 2) + 35 ' used in both cases ' replace 4
rect.X = sum
checkboxHeader231 = New CheckBox()
With checkboxHeader231
.BackColor = Color.Transparent
End With
checkboxHeader231.Name = "checkboxHeader1"
checkboxHeader231.Size = New Size(18, 18)
checkboxHeader231.Location = rect.Location
AddHandler checkboxHeader231.CheckedChanged, AddressOf checkboxHeader231_CheckedChanged
DataGridView1.Controls.Add(checkboxHeader231)
Private headerBox As CheckBox
Private Sub show_checkBox()
Dim checkboxHeader As CheckBox = New CheckBox()
Dim rect As Rectangle = PendingApprovalServiceListingDataGridView.GetCellDisplayRectangle(4, -1, True)
rect.X = 20
rect.Y = 12
With checkboxHeader
.BackColor = Color.Transparent
End With
checkboxHeader.Name = "checkboxHeader"
checkboxHeader.Size = New Size(14, 14)
checkboxHeader.Location = rect.Location
AddHandler checkboxHeader.CheckedChanged, AddressOf checkboxHeader_CheckedChanged
PendingApprovalServiceListingDataGridView.Controls.Add(checkboxHeader)
End Sub
Private Sub checkboxHeader_CheckedChanged(ByVal sender As Object, ByVal e As EventArgs)
headerBox = DirectCast(PendingApprovalServiceListingDataGridView.Controls.Find("checkboxHeader", True)(0), CheckBox)
For Each row As DataGridViewRow In PendingApprovalServiceListingDataGridView.Rows
row.Cells(0).Value = headerBox.Checked
Next
End Sub

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