i me using e.HasMorePages with code
For x As Integer = RowNo To dgv.Rows.Count - 1
Dim mypen As New Pen(Color.Black, 6)
e.Graphics.DrawString(dgv.Rows(x - 1).Cells(0).Value.ToString(), f, Brushes.Black, 645, yElementy)
If RowNo Mod 6 = 0 Then
RowNo += 1
e.HasMorePages = True
Exit For
End If
RowNo += 1
Next
how to using e.HasMorePages With code
For Each myRow In dtn.Rows
ListView1.Items.Add(n + ListView1.Items.Count + 1)
ListView1.Items(ListView1.Items.Count - 1).SubItems.Add(myRow.Item(13).ToString())
ListView1.Items(ListView1.Items.Count - 1).SubItems.Add(myRow.Item(5).ToString())
ListView1.Items(ListView1.Items.Count - 1).SubItems.Add(myRow.Item(14).ToString())
'i want to add here
Next
Typical layout: count variable(class level) for remembering what position we are at in the items printing. I like a List(Of String) for looping and printing. Inside the printPage event you need to have a variable for what row(y axis) your printing the records to and increment it with each iteration. Since it's graphics based you can also use a Rectangle structure and print contents to it using a StringFormat object for text wrapping and layout.
Print Document
Example off the top of my head - not tested.
Public Class Form1 ' your form name here
Private count As Integer
Private row As Integer
Private Sub print_Page(...) Handles ...
row = 100 'starting point from the top
Using p As New Pen(Brushes.Bisque) 'self disposing graphics object
'we use the variable here to know where we are if we have to go to next page
Dim rowCount = dg.Rows.Count - 1
For i As Integer = count To rowCount
e.Graphics.DrawString({value},p, Font, x, y)
row += 16 'basically the font height and some space in-between
If row = e.MarginBounds.Bottom - 20 Then
e.HasMorePages = True
If i <> rowCount Then 'are we on the last row?
count = i ' remember where we left off
Exit Sub ' cause this event will fire again and we need to start over
End If
End If
Next
End Using
End Sub
'...
End Class
Public Class frmTestHasMorePages
Dim Font12 As Font = New Drawing.Font("Arial", 12, FontStyle.Regular)
Dim Font8 As Font = New Drawing.Font("Arial", 8, FontStyle.Regular)
Dim sBrush As Drawing.Brush
Private Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
Static count As Integer
Static topMargin As Integer = 50
Static line As Integer
Static s, z As Integer
Dim linesPerPage = 65
Dim lineCount = 350
Static totalpages As Integer = IIf(lineCount Mod linesPerPage = 0, (lineCount / linesPerPage), (lineCount / linesPerPage) + 1)
sBrush = Brushes.Black
Dim pageBottom = e.PageBounds.Bottom
For i As Integer = count To lineCount
If z > lineCount Then
sBrush = Brushes.Blue
e.Graphics.DrawString("Page " & s + 1 & "/" & totalpages, Font8, sBrush, 750, pageBottom - 20)
sBrush = Brushes.Red
e.Graphics.DrawString("End of document ", Font8, sBrush, 50, pageBottom - 20)
e.HasMorePages = False
Exit Sub
End If
e.Graphics.DrawString("Testing hasmorepages with different options " & z, Font12, sBrush, 45, (i * 16) + topMargin)
line += 15
z += 1
If i = linesPerPage AndAlso s <= totalpages Then
e.HasMorePages = True
sBrush = Brushes.Blue
s += 1
e.Graphics.DrawString("Page " & s & "/" & totalpages, Font8, sBrush, 750, pageBottom - 20)
e.Graphics.DrawString("Continued...", Font8, sBrush, 50, pageBottom - 20)
i = 0
If i <> lineCount Then REM if it is the last line to print
Exit Sub
End If
End If
Next
End Sub
End Class
Related
I have a from which contains some PictureBoxes. They can be from one to many.
I create them at run-time depending on the existence of specific folders.
I create them and place them the one next to each other. This means that with a scrollable form I can view all of them easy.
My question is this: How do I position them in "rows"? For a specific form size, there can be 5 labels next to each other and infinite rows of them
How do I achieve this?
My (working) code:
Public allSeries As IEnumerable(Of String) = System.IO.Directory.EnumerateDirectories(root)
For i As Integer = 1 To allSeries.Count
Dim pb As New Windows.Forms.PictureBox With {
.Name = "pb" & i.ToString,
.Size = New Drawing.Size(500, 500),
.Location = New Point(5, 5),
.BorderStyle = BorderStyle.FixedSingle,
.SizeMode = PictureBoxSizeMode.Zoom,
.Image = Image.FromFile(allSeries(i - 1).ToString + "\sImage.jpg"),
.Tag = traveldestination, 'Store Directory path
.Cursor = Cursors.Hand}
Me.Controls.Add(pb)
For i As Integer = 2 To allSeries.Count
With Me
.Controls.Item("pb" + i.ToString).Left = .Controls.Item("pb" + (i - 1).ToString).Left + 520
End With
Next
My (bad) and (not workng) code:
Dim pbsOnForm As Integer = 13 'total PictureBoxes on Form /for this instance
Dim pbsOnRow As Integer = 5 'PictureBoxes that "fit" in a row /for this intance)
For i As Integer = 1 To pbsOnForm
If i <= pbsOnRow Then
Me.Controls.Item("pb" + i.ToString).Top = Me.Controls.Item("pb" + i.ToString).Top
End If
If i > pbsOnRow And i <= 10 Then
Me.Controls.Item("pb" + i.ToString).Top = Me.Controls.Item("pb" + (i - pbsOnRow).ToString).Top
End If
Works, but when the PcrureBoxes will be more than 10, I do not know......
While using the TableLayoutPanel would fulfill most cases for this and is probably the best way to achieve this, here is some code to align the PictureBox's in row / column.
First we want to setup a method to handle the positioning. We need some variables scoped to the Form.
Dim counter As Integer = 0
Dim xPos As Integer = 5
Dim yPos As Integer = 5
Now we use these variables in a method that sets the location.
Private Sub PositionPictureBox(pb As PictureBox, Optional imgPerRow As Integer = 5)
pb.Location = New Point(xPos, yPos)
counter += 1
If counter = imgPerRow Then
counter = 0
xPos = 5
yPos = pb.Location.Y + pb.Height + 5
Else
xPos = pb.Location.X + pb.Width + 5
End If
End Sub
Finally we call the method when the PictureBox is instantiated.
For i As Integer = 1 To allSeries.Count
Dim pb As New Windows.Forms.PictureBox
With pb
.Name = "pb" & i.ToString()
.Size = New Drawing.Size(50, 50)
.Location = New Point(5, 5)
.BorderStyle = BorderStyle.FixedSingle
.SizeMode = PictureBoxSizeMode.Zoom
.Image = Image.FromFile("...")
.Tag = allSeries(i)
.Cursor = Cursors.Hand
End With
PositionPictureBox(pb)
Me.Controls.Add(pb)
Next
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.
I am writing a snake game in visual studio in visual basic.
The playing field is a 2D Array of PictureBoxes. My Snake is a 1D array as type Point. The snake array is called 'Snake'.
When the form loads, Snake(0) is set as New Point(1, 1). I have created a sub routine that moves the snake depending on the arrow key the user presses. This is under a timer. Snake(0) (The snake head) is set to equal Snake(0) + direction (direction is a variable altered by the arrow key that the user presses, eg. when up is pressed direction is set to x: 0 and y: -1)
When snake(0) hits a piece of food, the amount of elements in the snake array is set to the length of the array. EG(If snake(0) = foodPosition Then ReDim Preserve snake(snake.Length) End If)
I have created a loop, also under the timer, to make the body of the snake follow the head (eg. snake(2) = snake(1) and snake(1) = snake(0) but can't get it to work)
Code:
Public Class frmPlayfield
'Food Creating and Grow Snake Variables
Dim randF As New Random
Dim foodPointX As Integer = randF.Next(0, 32)
Dim foodPointY As Integer = randF.Next(0, 32)
'Play Field Variables
Dim playMaxWidth As Integer = 32
Dim playMaxHeight As Integer = 32
Dim boxSize As Integer = 16 'Size of PictureBox
Dim boxArray(,) As PictureBox 'PictureBox Array
'Snake Stuff Variable
Dim snake(1) As Point 'Snake array
Dim direction As New Point(1, 0) 'Direction for snake movement
Private Sub frmPlayfield_Load(sender As Object, e As EventArgs) Handles MyBase.Load
ReDim boxArray(playMaxWidth, playMaxHeight)
For x As Integer = 0 To playMaxWidth
For y As Integer = 0 To playMaxHeight
boxArray(x, y) = New PictureBox
boxArray(x, y).Width = boxSize
boxArray(x, y).Height = boxSize
boxArray(x, y).Top = y * boxSize
boxArray(x, y).Left = x * boxSize
boxArray(x, y).Visible = True
boxArray(x, y).BackColor = Color.White
boxArray(x, y).BorderStyle = BorderStyle.FixedSingle
Me.Controls.Add(boxArray(x, y))
Next
Next
Me.ClientSize = New Size((playMaxWidth + 1) * boxSize, (playMaxHeight + 1) * boxSize)
snake(0) = New Point(1, 1) 'Creates snake head
boxArray(foodPointX, foodPointY).BackColor = Color.Red
End Sub
Private Function createBox(x As Integer, y As Integer, bSize As Integer) As PictureBox
Dim tempBox As New PictureBox
tempBox.Width = bSize
tempBox.Height = bSize
tempBox.Top = y * bSize
tempBox.Left = x * bSize
tempBox.Visible = True
tempBox.BackColor = Color.White
tempBox.BorderStyle = BorderStyle.FixedSingle
Me.Controls.Add(tempBox)
Return tempBox
End Function
Private Sub Food()
If snake(0).X = foodPointX And snake(0).Y = foodPointY Then
ReDim Preserve snake(snake.Length) 'Increases the amount of elements in the snake array.
For j As Integer = 0 To 0
foodPointX = randF.Next(0, 32)
foodPointY = randF.Next(0, 32)
boxArray(foodPointX, foodPointY).BackColor = Color.Red
Next
End If
For h As Integer = snake.Length - 1 To snake.GetUpperBound(0)
snake(h) = snake(snake.Length - 2)
Next
End Sub
Private Sub CheckBoundsAndMovement()
For i As Integer = 0 To snake.GetUpperBound(0)
boxArray(snake(i).X, snake(i).Y).BackColor = Color.White 'Loop to change the whole snake black
Next
snake(1) = snake(0)
snake(0) = snake(0) + direction
If snake(0).X > playMaxWidth Then
snake(0).X -= (playMaxWidth + 1)
End If
If snake(0).X < 0 Then
snake(0).X += (playMaxWidth + 1)
End If 'Four If statements to check if the snake has gone outside the play area.
If snake(0).Y > playMaxWidth Then
snake(0).Y -= (playMaxWidth + 1)
End If
If snake(0).Y < 0 Then
snake(0).Y += (playMaxWidth + 1)
End If
For k As Integer = 0 To snake.GetUpperBound(0)
boxArray(snake(k).X, snake(k).Y).BackColor = Color.Black 'Loop to make the whole snake black
Next
End Sub
Private Sub timGameTick_Tick(sender As Object, e As EventArgs) Handles timGameTick.Tick
Food()
CheckBoundsAndMovement()
End Sub
Private Sub frmPlayfield_KeyDown(sender As Object, e As KeyEventArgs) Handles MyBase.KeyDown 'Subroutine for direction
Select Case (e.KeyCode)
Case Keys.Up
direction = New Point(0, -1)
Case Keys.Down
direction = New Point(0, 1)
Case Keys.Left
direction = New Point(-1, 0)
Case Keys.Right
direction = New Point(1, 0)
End Select
End Sub
End Class
This works fine after I eat the first piece of food. The snake of length 2 is increased to length 3. But when I eat another piece of food the end of the snake is left behind at the spot where the food was eaten.
Ok - It looks like I found the problems -
First off - you defined the snake array as Dim snake (1) As Point this created the array with two elements instead of 1
Next, in your Food sub, the loop to roll the pixels back along the snake should be done every time the snake moves, not just when food is eaten. So I moved it into the CheckBoundsAndMovement sub to replace line 4 of that sub which only copied the location of the head to the next point back rather than the whole snake. But of course trying to execute the loop when the length of the snake was only one pixel would result in an out of range exception on the array, so added an If statement to only execute the loop if the length of snake is more than 1.
Also the direction of the loop in your code was in increasing order. To do it properly it should be in decreasing order. This way, the loop overwrites the point representing the end of the tail with the next point forward and so on. Finally, the new location for the head is entered into snake(0)
So - here it is -
Public Class frmPlayfield
'Food Creating and Grow Snake Variables
Dim randF As New Random
Dim foodPointX As Integer = randF.Next(0, 32)
Dim foodPointY As Integer = randF.Next(0, 32)
'Play Field Variables
Dim playMaxWidth As Integer = 32
Dim playMaxHeight As Integer = 32
Dim boxSize As Integer = 16 'Size of PictureBox
Dim boxArray(,) As PictureBox 'PictureBox Array
'Snake Stuff Variable
Dim snake(0) As Point 'Snake array
Dim direction As New Point(1, 0) 'Direction for snake movement
Private Sub frmPlayfield_Load(sender As Object, e As EventArgs) Handles MyBase.Load
ReDim boxArray(playMaxWidth, playMaxHeight)
For x As Integer = 0 To playMaxWidth
For y As Integer = 0 To playMaxHeight
boxArray(x, y) = New PictureBox
boxArray(x, y).Width = boxSize
boxArray(x, y).Height = boxSize
boxArray(x, y).Top = y * boxSize
boxArray(x, y).Left = x * boxSize
boxArray(x, y).Visible = True
boxArray(x, y).BackColor = Color.White
boxArray(x, y).BorderStyle = BorderStyle.FixedSingle
Me.Controls.Add(boxArray(x, y))
Next
Next
Me.ClientSize = New Size((playMaxWidth + 1) * boxSize, (playMaxHeight + 1) * boxSize)
snake(0) = New Point(1, 1) 'Creates snake head
boxArray(foodPointX, foodPointY).BackColor = Color.Red
End Sub
Private Function createBox(x As Integer, y As Integer, bSize As Integer) As PictureBox
Dim tempBox As New PictureBox
tempBox.Width = bSize
tempBox.Height = bSize
tempBox.Top = y * bSize
tempBox.Left = x * bSize
tempBox.Visible = True
tempBox.BackColor = Color.White
tempBox.BorderStyle = BorderStyle.FixedSingle
Me.Controls.Add(tempBox)
Return tempBox
End Function
Private Sub Food()
If snake(0).X = foodPointX And snake(0).Y = foodPointY Then
ReDim Preserve snake(snake.Length)
foodPointX = randF.Next(0, 32)
foodPointY = randF.Next(0, 32)
boxArray(foodPointX, foodPointY).BackColor = Color.Red
End If
End Sub
Private Sub CheckBoundsAndMovement()
For i As Integer = 0 To snake.GetUpperBound(0)
boxArray(snake(i).X, snake(i).Y).BackColor = Color.White 'Loop to change the whole snake white
boxArray(snake(i).X, snake(i).Y).Update()
Next
If snake.Length > 1 Then
For i As Integer = snake.GetUpperBound(0) To 1 Step -1
snake(i) = snake(i - 1)
Next
End If
snake(0) = snake(0) + direction
If snake(0).X > playMaxWidth Then
snake(0).X -= (playMaxWidth + 1)
End If
If snake(0).X < 0 Then
snake(0).X += (playMaxWidth + 1)
End If 'Four If statements to check if the snake has gone outside the play area.
If snake(0).Y > playMaxWidth Then
snake(0).Y -= (playMaxWidth + 1)
End If
If snake(0).Y < 0 Then
snake(0).Y += (playMaxWidth + 1)
End If
For k As Integer = 0 To snake.GetUpperBound(0)
boxArray(snake(k).X, snake(k).Y).BackColor = Color.Black 'Loop to make the whole snake black
Next
End Sub
Private Sub timGameTick_Tick(sender As Object, e As EventArgs) Handles timGameTick.Tick
Food()
CheckBoundsAndMovement()
End Sub
Private Sub frmPlayfield_KeyDown(sender As Object, e As KeyEventArgs) Handles MyBase.KeyDown 'Subroutine for direction
Select Case (e.KeyCode)
Case Keys.Up
direction = New Point(0, -1)
Case Keys.Down
direction = New Point(0, 1)
Case Keys.Left
direction = New Point(-1, 0)
Case Keys.Right
direction = New Point(1, 0)
End Select
End Sub
End Class
I'm failing at signaling my printer to start a new page. It continues to print on page 1 after I set e.HasMorePages = True. With my font, I can cleanly print ~ 30 lines per page and still maintain the border
'print the text
'create a string array from the listView equipment items
Dim equip() As classReportObj
ReDim equip(0 To lstReport.Items.Count - 1)
For i = 0 To lstReport.Items.Count - 1
equip(i) =
New classReportObj() With {.name = lstReport.Items(i).Text, .type = lstReport.Items(i).SubItems(1).Text,
.completeTests = lstReport.Items(i).SubItems(2).Text, .incompleteTests = lstReport.Items(i).SubItems(3).Text,
.status = lstReport.Items(i).SubItems(4).Text}
Next i
'get the coordinates for the first row and the columns
Dim y As Integer = e.MarginBounds.Top
Dim x0 As Integer = e.MarginBounds.Left
Dim x1 As Integer = x0 + 150
Dim x2 As Integer = x1 + 150
Dim x3 As Integer = x2 + 150
Dim x4 As Integer = x3 + 120
Dim headerFont As New Font("Times New Roman", 10)
Dim maxLines As Integer 'maximum number of lines per page
maxLines = 30 '30 lines per page, including headers
Dim lineCount As Integer 'counts lines per printed page
'make a new font to use
Using theFont As New Font("Times New Roman", 10)
'draw the column headers
e.Graphics.DrawString("Project: " & project.name & " " & thisReportType & " Report, " & Now, theFont, Brushes.Black, x0, y)
e.Graphics.DrawString("Name", headerFont, Brushes.Black, x0, y + 30)
e.Graphics.DrawString("Type", headerFont, Brushes.Black, x1, y + 30)
e.Graphics.DrawString("Complete Tests", headerFont, Brushes.Black, x2, y + 30)
e.Graphics.DrawString("Incomplete Tests", headerFont, Brushes.Black, x3, y + 30)
e.Graphics.DrawString("Status", headerFont, Brushes.Black, x4, y + 30)
'mmove Y down for the next row
y += 60
Dim nameMax As Integer 'max characters for name
Dim typeMax As Integer 'max characters for type
'loop through each equipment to display the data
For Each aEquip In equip
'set the max character length for name and type
If aEquip.name.Length < 23 Then
nameMax = aEquip.name.Length
Else
nameMax = 23
End If
'
If aEquip.type.Length < 23 Then
typeMax = aEquip.type.Length
Else
typeMax = 23
End If
'display the equipment values
e.Graphics.DrawString(aEquip.name.Substring(0, nameMax), theFont, Brushes.Black, x0, y)
e.Graphics.DrawString(aEquip.type.Substring(0, typeMax), theFont, Brushes.Black, x1, y)
e.Graphics.DrawString(aEquip.completeTests, theFont, Brushes.Black, x2, y)
e.Graphics.DrawString(aEquip.incompleteTests, theFont, Brushes.Black, x3, y)
e.Graphics.DrawString(aEquip.status, theFont, Brushes.Black, x4, y)
'move Y down for the next row
y += 30
'increment the line counter for each piece of equipment
lineCount = lineCount + 1
'if we've reached the maximum number of lines per page
If (lineCount Mod maxLines) = 0 Then
'draw a box around it all
e.Graphics.DrawRectangle(Pens.Black, x0, e.MarginBounds.Top + 30, x4 - x0 + 100, y - e.MarginBounds.Top - 30)
e.HasMorePages = True 'But it doesn't start a new page, it continues printing page 1 unless I exit
Else
e.HasMorePages = False
End If
Next
End Using
'draw a box around it all
e.Graphics.DrawRectangle(Pens.Black, x0, e.MarginBounds.Top + 30, x4 - x0 + 100, y - e.MarginBounds.Top - 30)
'only printing one page (for now)
e.HasMorePages = False
End Sub
You seem not to understand what e.HasMorePages actually does. All it does is cause the PrintPage event to be raised again. If all your PrintPage event handler does is print the first page then that's all you see printed over and over.
The PrintPage event handler is supposed to print one page. The very first thing you would usually do in that event handler is determine what page needs to be printed. That is generally going to require that you keep some sort of count OUTSIDE the event handler.
That count might be specifically how many pages have been printed or it might be an index into a list of records or something else. Whatever it is, it needs to tell you insider the PrintPage event handler how to get what needs to be printed on the current page.
Here's an example that will print a list of Strings, five to a page:
Private lines As New List(Of String)
Private overallRecordIndex As Integer
Private pageNumber As Integer
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
overallRecordIndex = 0
pageNumber = 1
PrintDocument1.Print()
End Sub
Private Sub PrintDocument1_PrintPage(sender As Object, e As Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
Dim pageRecordIndex = 0
Dim yOffset = 10
Do While pageRecordIndex < 5 AndAlso overallRecordIndex < lines.Count
e.Graphics.DrawString(String.Format("Page {0}, Record {1}: {2}",
pageNumber,
overallRecordIndex,
lines(overallRecordIndex)),
Me.Font,
Brushes.Black,
10,
yOffset)
overallRecordIndex += 1
pageRecordIndex += 1
yOffset += 20
Loop
e.HasMorePages = (overallRecordIndex < lines.Count)
If e.HasMorePages Then
pageNumber += 1
End If
End Sub
I am computing the ROI with a moving rectangle and extracting the ROI to compute the standard deviation, mean, area and Pixel value coordinates X and Y in a seperate form2 by clicking the mouse. At this juncture I am trying to pass a function from the main Form that loads the Image and displays the rectangle to another Form that has the displayed properties of the mean and standard deviation etc. However, I'm receiving errors in runtime in the function that contains the standard deviation. The error displayed is
Index was outside the bounds of the array.
It is displayed at the end of this portion of the code in the function StD, i.e at the end of the mean part'
SD(count) = Double.Parse(pixelcolor.R) + Double.Parse(pixelcolor.G) + Double.Parse(pixelcolor.B) - mean
what is this actually saying and how can I fix this situation. Any tips and ideas, thanks.
My code is at the bottom
enterPublic Function StD(ByVal image As Bitmap, ByVal mean As Double, ByVal meancount As Integer) As Double
Dim SD(SquareHeight * SquareWidth) As Double
Dim count As Integer = 0
For i = 0 To SquareWidth
For j = 0 To SquareHeight
Dim pixelcolor As Color = image.GetPixel(i, j)
SD(count) = Double.Parse(pixelcolor.R) + Double.Parse(pixelcolor.G) + Double.Parse(pixelcolor.B) - mean
count += 1
Next
Next
Dim SDsum As Double = 0
For i = 0 To count
SDsum = SDsum + SD(i)
Next
SDsum = SDsum / (SquareHeight * SquareWidth)
SDsum = ((SDsum) ^ (1 / 2))
Return SDsum
End Function code here
I would like to pass this using the code below
enterPrivate Sub PictureBox1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
Dim mean As Double = 0
Dim meancount As Integer = 0
Dim bmap As New Bitmap(400, 400)
bmap = PictureBox1.Image
Dim colorpixel As Color = bmap.GetPixel(e.X, e.Y)
' Dim pixels As Double = colorpixel.R + colorpixel.G + colorpixel.B
If e.Button = Windows.Forms.MouseButtons.Left AndAlso Rect.Contains(e.Location) Then
If (PictureBox1.Image Is Nothing) Or (PictureBox1.Height - (e.Y + SquareHeight) < 0) Or (PictureBox1.Width - (e.X + SquareWidth) < 0) Then
Else
Dim ROI As New Bitmap(400, 400)
Dim x As Integer = 0
Dim countx As Integer = 0
Dim county As Integer = 0
For i = e.X To (e.X + SquareWidth)
For j = (e.Y + x) To (e.Y + SquareHeight)
Dim pixelcolor As Color = bmap.GetPixel(i, j)
ROI.SetPixel(countx, county, pixelcolor)
mean = mean + pixelcolor.R + pixelcolor.G + pixelcolor.B
county += 1
meancount += 1
Next
county = 0
countx += 1
x = x + 1
Next
mean = mean / (meancount * 3)
Dim SD = mean - 75
Dim area As Integer = (SquareHeight * SquareWidth)
Dim anotherForm As Form2
anotherForm = New Form2(mean, StD(bmap, mean, meancount), area, 34)
anotherForm.Show()
End If
End If
' Catch ex As Exception
' MessageBox.Show(ex.Message())
' End Try
End Sub code here
To be displayed with this code
enter Public Sub New(ByVal mean As Double, ByVal StD As Double, ByVal Area As Integer, ByVal pixel As Double)
MyBase.New()
InitializeComponent()
TextBox1.Text = mean.ToString()
TextBox2.Text = StD.ToString()
TextBox3.Text = Area.ToString()
TextBox4.Text = pixel.ToString()
End Sub code here
The problem probably is because of these lines:
For i = 0 To SquareWidth
For j = 0 To SquareHeight
Try using this instead:
For i = 0 To SquareWidth - 1
For j = 0 To SquareHeight - 1