VB Net Graphics DrawString construct Fail - vb.net

I have NO idea what is wrong with my construct in the Second Graphics.DrawString line of code
My Question is Why is the construction of that line of code FAILING and the line above it does Not Fail
This is the FAILING line of code
e.Graphics.DrawString(strTo, 12, Brushes.Red, 45, 50)
Private Sub pdDoc_PrintPage(sender As Object, e As Printing.PrintPageEventArgs) Handles pdDoc.PrintPage
Dim fontSize As Integer = 30
Dim labelFont As Font = New Font("Times New Roman", fontSize, FontStyle.Bold)
Dim strTo As String = "Kitchen"
Dim lblArray(2) As String
lblArray(0) = "Kitchen"
e.Graphics.DrawString(lblArray(0), labelFont, Brushes.Black, 500, 950)
e.Graphics.DrawString(strTo, 12, Brushes.Red, 45, 50)
After reading the two answers and Here is my updated FIX for the error's in the line of code above
Dim labelFont As Font = New Font("Times New Roman", fontSize, FontStyle.Bold)
Dim strTo As Object = "Kitchen"
e.Graphics.DrawString(strTo.ToString, labelFont, Brushes.Red, 300, 300)

I've taken the liberty of aligning your commas between the working and not:
e.Graphics.DrawString(lblArray(0), labelFont, Brushes.Black, 500, 950)
e.Graphics.DrawString(strTo , 12 , Brushes.Red , 45 , 50 )
^^^^^^^^^
What kind of Font is 12 ?

The first DrawString is OK, but the second one is incorrect.
public void DrawString (string s, System.Drawing.Font font, System.Drawing.Brush brush, float x, float y, System.Drawing.StringFormat format);
#CaiusJard has already identified the error, so I am clarifying more.
Here it accepts a Font object, not Integer. By 12 I think you have confused with size. First you can declare a font object with:
Dim myFont As Font = New Font("FONT NAME",12)
Then you can use myFont instead of 12.

Related

String.Format alignment

I'm having trouble aligning my four columns:
My string format for the titles works properly. When I read the next line and put it into a list, the String.Format takes the video name and creates the columns adjusting to the video names length. How can I fix this?
Private Sub pdPrint_PrintPage(sender As Object, e As Printing.PrintPageEventArgs) Handles pdPrint.PrintPage
e.Graphics.DrawString("Movie Collection", New Font("Courier", 20, FontStyle.Bold), Brushes.Black, 300, 10)
e.Graphics.DrawString(String.Format("{0, -20} {1,-20} {2, -20} {3,-20}", "VIDEO NAME", "YEAR PRODUCED", "RUNNING TIME", "RATING"), New Font("Courier", 12, FontStyle.Bold), Brushes.Black, 10, 70)
Using reader As New StreamReader("testing.txt")
Dim intVertPosition As Integer = 90
While Not reader.EndOfStream
Dim videoName As String = reader.ReadLine()
Dim yearProduced As String = reader.ReadLine()
Dim runningTime As String = reader.ReadLine()
Dim rating As String = reader.ReadLine()
Dim extraline As String = reader.ReadLine()
e.Graphics.DrawString(String.Format("{0, -30} {1,30} {2, 30} {3,30}", videoName.ToString(), yearProduced.ToString(), runningTime.ToString(), rating.ToString()), New Font("Courier", 12, FontStyle.Regular), Brushes.Black, 10, intVertPosition)
intVertPosition += 14
End While
End Using
End Sub
e.Graphics.DrawString(..., New Font("Courier", 20, FontStyle.Bold), ...)
This is where the problem started. This kind of formatting can only work correctly if the width a space is the same as the width of a letter. Or in other words, it requires a fixed-pitch font. But you can clearly tell from the screen-shot that you got a proportionally pitched font. So, roughly, the more text in the first column, the more it pushes out the next column.
This happened because you picked "Courier". It is the name of a legacy device font, useful only in programs that were written 27 years ago. Graphics.DrawString() requires a scalable font outline, a True-Type font to be specific, and cannot use device fonts. So the font mapper kicks in to provide an alternative, unfortunately it isn't smart enough to recognize that you wanted a fixed-pitch font.
Fix the problem by using "Courier New" instead.

How to perfectly center a character in a box with DrawRectangle and DrawString..?

Given the following VB.Net code sample, how can the characters be drawn in the boxes with perfect vertical centering..? If one looks closely, some are not vertically centered, and have a tiny vertical offset.
LineAlignment = StringAlignment.Center is already specified, but it's not perfect. Perhaps there are font or display properties that can be used to calculate the slight adjustment that is needed? If not in .Net, then perhaps in Windows API calls?
In this line of the code, an offset is applied, but it was determined by experimentation. I would like to find a more precise calculation.
p.Offset(0, fontSize * 0.1)
I checked the .Net Font class, but I didn't see any native properties that could be used as described. But then, I might not be understanding what's right in front of me. I also Googled for an answer, but got too much information.
https://msdn.microsoft.com/en-us/library/system.drawing.font(v=vs.110).aspx
Public Class Form1
Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
Dim g As Graphics = e.Graphics
Dim fontSize As Integer = 24
Dim boxSize = 30
DrawTargetBox(g, New Point(40, 40), boxSize, "X", "Arial", fontSize)
DrawTargetBox(g, New Point(80, 40), boxSize, "X", "Times New Roman", fontSize)
DrawTargetBox(g, New Point(120, 40), boxSize, "X", "Courier New", fontSize)
DrawTargetBox(g, New Point(160, 40), boxSize, "X", "Calibri", fontSize)
DrawTargetBox(g, New Point(200, 40), boxSize, "X", "Tahoma", fontSize)
DrawTargetBox(g, New Point(240, 40), boxSize, "X", "Comic Sans", fontSize)
End Sub
Private Sub DrawTargetBox(g As Graphics, p As Point, boxSize As Integer, boxLabelText As String, fontName As String, fontSize As Integer)
g.DrawRectangle(New Pen(Brushes.Black, 1.0), New Rectangle(p.X - (boxSize / 2), p.Y - (boxSize / 2), boxSize, boxSize))
Dim textVerticalOffset = (boxSize / -2) - (fontSize)
p.Offset(0, fontSize * 0.1) 'vertical squidge to hit the center of the point/box
Dim strFormat As New StringFormat(StringFormatFlags.NoClip)
strFormat.Alignment = StringAlignment.Center
strFormat.LineAlignment = StringAlignment.Center
g.DrawString(boxLabelText, New Font(fontName, fontSize), Brushes.Black, p, strFormat)
End Sub
End Class

Pixelated Text When Using ObjectListView Custom Renderer

I found an example online of how to create a business card listview item using the ObjectListView. It demonstrates using a custom renderer to manually draw each Tile within the control.
The sample involves creating buffered graphics and manually drawing each item. I have this working, however, I am finding that all text I draw on the tile is looking pixelated (no matter what settings I use), especially if I draw small text. For example, using a default system font on a normal form looks fine, but in my renderer it looks jagered.
The code looks like this:
Imports BrightIdeasSoftware
Imports System.Drawing.Drawing2D
Imports System.IO
Public Class StoreListRenderer
Inherits AbstractRenderer
Public Overrides Function RenderItem(e As DrawListViewItemEventArgs, g As Graphics, itemBounds As Rectangle, rowObject As Object) As Boolean
' If we're in any other view than Tile, return false to say that we haven't done
' the rendereing and the default process should do it's stuff
Dim olv As ObjectListView = TryCast(e.Item.ListView, ObjectListView)
If olv Is Nothing OrElse olv.View <> View.Tile Then
Return False
End If
' Use buffered graphics to kill flickers
Dim buffered As BufferedGraphics = BufferedGraphicsManager.Current.Allocate(g, itemBounds)
g = buffered.Graphics
g.Clear(olv.BackColor)
g.SmoothingMode = ObjectListView.SmoothingMode
g.TextRenderingHint = ObjectListView.TextRenderingHint
If e.Item.Selected Then
Me.BorderPen = Pens.White
Me.HeaderBackBrush = New SolidBrush(olv.HighlightBackgroundColorOrDefault)
Else
Me.BorderPen = New Pen(Color.FromArgb(&H33, &H33, &H33))
Me.HeaderBackBrush = New SolidBrush(Color.FromArgb(&H33, &H33, &H33))
End If
DrawStoreCard(g, itemBounds, rowObject, olv, DirectCast(e.Item, OLVListItem))
' Finally render the buffered graphics
buffered.Render()
buffered.Dispose()
' Return true to say that we've handled the drawing
Return True
End Function
Friend BorderPen As New Pen(Color.FromArgb(&H33, &H33, &H33))
Friend TextBrush As Brush = New SolidBrush(Color.FromArgb(&H22, &H22, &H22))
Friend HeaderTextBrush As Brush = Brushes.AliceBlue
Friend HeaderBackBrush As Brush = New SolidBrush(Color.FromArgb(&H33, &H33, &H33))
Friend BackBrush As Brush = Brushes.LemonChiffon
Friend BackgroundBrush As Brush = New SolidBrush(Color.FromArgb(38, 38, 38))
Public Sub DrawStoreCard(g As Graphics, itemBounds As Rectangle, rowObject As Object, olv As ObjectListView, item As OLVListItem)
Try
Dim _store As StoreObject = TryCast(rowObject, StoreObject)
' Allow a border around the card
itemBounds.Inflate(-5, -5)
g.FillRectangle(BackgroundBrush, itemBounds)
Dim ColouredPanelRect As Rectangle = New Rectangle(itemBounds.Left + 7, itemBounds.Top + 7, 70, 70)
g.FillRectangle(Brushes.IndianRed, ColouredPanelRect)
Dim fmt As New StringFormat()
fmt.Alignment = StringAlignment.Center
fmt.LineAlignment = StringAlignment.Center
For i As Integer = 0 To olv.Columns.Count - 1
Dim column As OLVColumn = olv.GetColumn(i)
If column.IsTileViewColumn Then
'Draw Store Number
Using font As New Font(fontMgr("Mentone Lig"), 36, FontStyle.Regular, GraphicsUnit.Pixel)
g.TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAliasGridFit
g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
g.DrawString(_store.StoreID, font, BackgroundBrush, ColouredPanelRect, fmt)
End Using
'Draw Store Name
Using string_format As New StringFormat()
string_format.Alignment = StringAlignment.Center
string_format.LineAlignment = StringAlignment.Near
g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
g.TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAliasGridFit
g.DrawString(_store.StoreName.ToUpper, New Font("Segoe UI", 9, FontStyle.Regular), Brushes.White, itemBounds, string_format)
End Using
...
I have tried playing around AntiAlias and ClearType but both have the same affect.
UPDATE
Here are my results below with using the same font at the same size:
The text at the top represents a normal label placed on a form. The text at the bottom is text drawn on to a listview item (in Tile mode) using the code above. You can easily identify the difference and see that it is not as smooth. Also the larger I make the text the more unsmooth it gets. I have tried playing around with all the settings and currently have it set to:
g.TextRenderingHint = Drawing.Text.TextRenderingHint.ClearTypeGridFit
g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
g.CompositingQuality = Drawing2D.CompositingQuality.HighQuality
g.PixelOffsetMode = PixelOffsetMode.HighQuality
Thanks
Okay, I ended up working this out by going through the example again.
The problem was that I was dropping the scaling element from my code which seemed to be causing the pixilation of the text.
By adding the following code back in, it has corrected the smoothness of the text:
Dim size As SizeF = g.MeasureString(txt, font, CInt(itemBounds.Width), fmt)
g.TextRenderingHint = Drawing.Text.TextRenderingHint.ClearTypeGridFit
So my overall code looks like this:
Using font As New Font("Segoe UI", 9, FontStyle.Regular)
' Measure the height of the title
txt = column.GetStringValue(rowObject)
Dim size As SizeF = g.MeasureString(txt, font, CInt(itemBounds.Width), fmt)
g.TextRenderingHint = Drawing.Text.TextRenderingHint.ClearTypeGridFit
g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
g.CompositingQuality = Drawing2D.CompositingQuality.HighQuality
g.PixelOffsetMode = PixelOffsetMode.HighQuality
g.DrawString(txt, font, Brushes.LightGray, itemBounds, fmt)
End Using

muti line text with first line underline in datagridviewTextBoxCell Vb.net

I'm able to add the mutiline text in datagridViewtextboxcell by using Environment.NewLine while inserting. but I would like to add underline for 1st line. so how could i achive this in vb.net
now I'm handling the paint method of DGV for showing date in 2 color for date format(as like in first column).
Please find the attached image,
in that second last column for email and cell number i want to draw underline.
Thanks.
I'm answering my own question.
Handle the DataGridView1_CellPainting and call this method for specific cell/column.firstly seperate the string and render it with TextRenderer class 2 times with new location.
I don't know is this correct way, but it works.
Private Sub CellText_Underline(color As Color, e As DataGridViewCellPaintingEventArgs)
Dim text As String = e.FormattedValue.ToString()
Dim nameParts As String() = text.Split(" ")
Dim topLeft As New Point(e.CellBounds.X, CInt(e.CellBounds.Y + (e.CellBounds.Height / 4)))
Dim arialBold As New Font("Arial", 11, FontStyle.Regular Xor FontStyle.Underline)
TextRenderer.DrawText(e.Graphics, nameParts(0), arialBold, topLeft, color)
Dim topLeft_1 As New Point(e.CellBounds.X, CInt(e.CellBounds.Y + (e.CellBounds.Height / 4) + 5))
Dim s As Size = TextRenderer.MeasureText(nameParts(0), arialBold)
Dim p As New Point(topLeft_1.X, topLeft_1.Y + 12)
Dim arialBold_1 As New Font("Arial", 11, FontStyle.Regular)
TextRenderer.DrawText(e.Graphics, nameParts(1), arialBold_1, p, SystemColors.WindowText)
End Sub
Thanks.

Coloring in shapes in Visual Basic.Net?

I have a set of shapes created in visual basic that need to be colored in:
Public Class Form1
Private Sub btnDraw_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDraw.Click
Dim formSurface As Graphics = Me.CreateGraphics 'creates surface
Dim world As New Pen(Color.Black, 3)
formSurface.DrawRectangle(world, 250, 50, 300, 300) 'world
Dim roof As New Pen(Color.Black, 3)
Dim roof1 As New Point(325, 200)
Dim roof2 As New Point(475, 200)
Dim roof3 As New Point(400, 100)
Dim roof4 As New Point(400, 100)
Dim curvePoints As Point() = {roof1, roof2, roof3, roof4}
formSurface.DrawPolygon(roof, curvePoints) 'triangle roof
Dim body As New Pen(Color.Black, 3)
formSurface.DrawRectangle(body, 325, 200, 150, 150) 'square body
Dim sun As New Pen(Color.Black, 3)
formSurface.DrawEllipse(sun, 450, 75, 50, 50) 'sun
Dim door As New Pen(Color.Black, 3)
formSurface.DrawRectangle(door, 387, 300, 25, 50) 'door
End Sub
End Class
Everything works perfectly; the shapes are all generated where I want them to be. (I'm trying to draw a house) However, how do I color them in? Also, if I do, will the colors overlap (I want that to happen)?
Should I use some function like image.fill? I know that isn't right but I'm looking for something like that.
Thanks!
You want to use the formSurface.FillPolygon, FillRectangle, and FillEllipse commands. You can still use the Draw commands to create an outline with a different color than the fill.
The "Fill" commands need Brushes instead of pens. (Pens draw lines, brushes fill space.) The easiest type of brush to use would be like "Brushes.AliceBlue".