I have been able to create a PDF using iTextSharp in my VB .net code that looks almost exactly as I want it to. However, I am using a table with one column and multiple rows to display long text strings put together by using chunks and phrases. Some of the chunks contain text that is underlined. When there is underlined text in a phrase, the entire cell needs to be highlighted gray, and I am using the BackgroundColor property of PdfPCell for this.
The problem I am having is that the underline line falls outside of the cell boundaries (outside of the highlighting). I have tried many things to fix this such as setting a fixed cell height and then setting cell.VerticalAlignment to Element.ALIGN_TOP; using SetLeading with various values including (0, 0) which only made the problem worse; setting cell.Ascender to True; and changing padding values. I may have tried other things too, but for some reason, no matter what I try, the line for the underline text falls outside the highlighting. And, the highlighting goes right up to the bottom of the text in the cell above (which is why I tried playing with the SetLeading values.)
The image shows page 2 of my resulting PDF.
PDF with table
Below is and example of the sections of code that are implementing this - "outString1" and "outString2" are the output text strings that get appended to a single line. There is one Boolean value to determine if a chunk of text needs to be underlined, and one to determine if cell highlighting is needed - there are some cases where the cell might be highlighted but the text is not underlined. Any suggestions for how I can fix this?
Dim pdfTable As PdfPTable = New PdfPTable(1)
pdfTable.WidthPercentage = 100
'the next section is within a loop to create and load each cell
Dim P As New Phrase()
'Slisted is a Boolean value to determine need for underlining
If Slisted Then
P.Add(New Chunk(outString1, myULfont))
Else
P.Add(New Chunk(outString1, myfont))
End If
P.Add(New Chunk(outString2, myfont))
Dim cell As PdfPCell = New PdfPCell(P)
cell.Border = 0
cell.Padding = 0
'hilite is a Boolean value to determine whether
If hilite Then
cell.BackgroundColor = BaseColor.LIGHT_GRAY
End If
pdfTable.AddCell(cell)
'out of loop, load table into document
pdfDoc.Add(pdfTable)
An underline, by default, is a certain offset away from the text. Unfortunately, since you've killed off the padding on the table that offset is conflicting with the cell's layout. One option is that you should just change the padding as people have suggested. Another option, however, is to manually set the underline's offset of the Chunk on your own. Below is a sample of that:
Dim T As New PdfPTable(1)
For I = 1 To 10
''//Your chunk
Dim Ch As New Chunk("Hello", DocFont)
''//Wrap the chunk in a phrase
Dim p As New Phrase(Ch)
''//Wrap the phrase in a cell
Dim cell As PdfPCell = New PdfPCell(p)
''//Optional borders and padding
cell.Border = 0
cell.Padding = 0
''//This is just an example to do every other cell
If I Mod 2 = 0 Then
cell.BackgroundColor = BaseColor.LIGHT_GRAY
''//Set the thickness and offset from the text
Ch.SetUnderline(0.1, 0)
End If
T.AddCell(cell)
Next
Related
I'm trying to change the color of a portion of a string that is loaded into userform's label based on certain conditions. My attempt is to find the starting character and length of the string I want to format by using instr function and then loop through individual characters and change their .forecolor property.
startpoint = InStr(showformula, ListBoxValue)
endpoint = startpoint + Len(ListBoxValue)
For i = startpoint To endpoint
LabelMain.Characters(i).ForeColor = RGB(255, 0, 0)
Next i
Unfortunately, I am getting error on the LabelMain.Characters(i).ForeColor = RGB(255, 0, 0) as it looks like I cannot select individual characters in VBA's label userform.
Is there another way to change the font color of only portion of the label's caption?
Thank you!
Nope. If it's just a one off can just split your text into multiple labels and sit them on top of each other.
If your wanting something programmtic it would be a lot trickier, only solution I can think of would be to :
Create array of the widths of all characeters in your font set.
Calculate distance from edge of label where highlight text starts
Replace text with spaces equal to highlight text lenght
Create a new label over the top in correct position based on new distance.
set Lbl = MyForm.Contorls.Add("Forms.Label.1", "MyNewLabelName",true)
'Set properties of the lbl
I have small problem, does anyone know how to change position of existing dimensions and Notes in Part/Product using short macro.
I will shortly describe what I want to do and what kind of problem I have.
I have simple model (let say rectangle)
Inside this model I have dimensions and annotations created in FTA.
Next step is to drastically change position of this model (base model in point 0,0,0 and I want tochange it position to 150,10000,80 + rotation)
during this change some dimensions and annotations (Theirs position in 3D) are not fully following after geometry.
Because of that I would like to have simple macro to create new position of my dimensions and annotations after part update.
I have performed some simple tests code bellow
What I have noticed, when I set new position of the text:
Theoretically text change position but in 3D it stays in old position.
When edit my text by double click on it and then click OK my text translates to new position which was set in macro earlier. The same situation is when I would like to change frame of the text or content (I had AAA and I would like to have BBB), it's changes only when I open Text editor.
Set part1 = CATIA.ActiveDocument
Set Selection = part1.Selection
Set VisPropertySet = Selection.VisProperties
Selection.Search ("name='Text.1',all")
' get selected annotation here
Dim anAnnotation As Annotation
Set anAnnotation = CATIA.ActiveDocument.Selection.Item(1).Value
' get annotation on the DrawingText interface
Dim txtAnnotation As DrawingText
Set txtAnnotation = anAnnotation.Text.Get2dAnnot()
' get TPS view that contains annotation on the DrawingView interface
Dim vwTPSView As DrawingView
Set vwTPSView = txtAnnotation.Parent.Parent
' get coordinates on a view
Dim dX ' as Double
txtAnnotation.X = 0
txtAnnotation.Y = 30
txtAnnotation.FrameType = catEllipse
part1.Update
End Sub
Generally using Part.Update refreshes the annotation's position and text but you can also use:
Dim anAnnotation As Annotation
'Code here
anAnnotation.ModifyVisu 'This should work for both Texts and Dimensions
But if the above method does not work, you can try reseting the text on the annotation (It will work only for texts, and not for dimensions)
Dim vwTPSView As DrawingView
'Code here
vwTPSView.Text = vwTPSView.Text
Be carefull with this last methos though. If your text has any parameters or variables inside it, replacing the text will clear it.
I am creating an add-in using VB.NET VSTO for MS-Word. In this program I need to retrieve the details such as Location (Left, Top) and Size (Height, Weight) of all the images on the document. I also want to retrieve the page number where the image is located. I use the following code,
Dim i As Integer
For i = 1 To Globals.ThisAddIn.Application.ActiveDocument.InlineShapes.Count
If Globals.ThisAddIn.Application.ActiveDocument.InlineShapes(i).Type = Word.WdInlineShapeType.wdInlineShapePicture Then
strHeight = Globals.ThisAddIn.Application.ActiveDocument.InlineShapes(i).ScaleHeight()
strWidth = Globals.ThisAddIn.Application.ActiveDocument.InlineShapes(i).ScaleWidth()
End If
Next i
However, this can only retrieve the Size (Height, Weight). How to get the Location (Left, Top) and page number of the image?
By its very nature, an InlineShape doesn't have a positionable top and left. It's, well, inline, which means it exists in the text layer of the document and the location floats depending on the text and/or other content before it. If the item is on page 2, and you insert 25 lines of text or another picture before InlineShape(i), said shape will float down to page 3 (or 4 or whatever.)
The height and width ARE accessible, simply by using .Height and .Width. ScaleHeight and ScaleWidth are properties that reflect the size of the object in the document relative to the original size of the object. You probably want to store the height and width as strings, though, since the property returns a single (numeric) value. For height and width:
Dim i As Integer
Dim shp as InlineShape
For i = 1 To Globals.ThisAddIn.Application.ActiveDocument.InlineShapes.Count
shp = Globals.ThisAddIn.Application.ActiveDocument.InlineShapes(i)
If shp.Type = Word.WdInlineShapeType.wdInlineShapePicture Then
strHeight = shp.Height.ToString()
strWidth = shp.Width.ToString()
End If
Next i
To get the page number, you have to reference the range of the InlineShape.
shp.Range.get_Information(Word.WdInformation.wdActiveEndPageNumber)
You can also get the top and left position of the image (although it might not do you any good, depending on why you want it). The get_Information method also has wdHorizontalPositionRelativeToPage and wdVerticalPositionRelativeToPage
I have to create dynamic table layout panel with some controls with auto sized rows and and fixed columns size.
My problem is that i want to show whole checkbox text .
Any help
My code is
Dim textBox2 As New CheckBox()
textBox2.Text = "You forgot to add the ColumnStyles. Do this on a sample form first with the designer. Click the Show All Files icon in the Solution Explorer window. Open the node next to the form and double-click the Designer.vb file. "
textBox2.AutoSize = True
textBox2.Dock = DockStyle.Top
'' textBox2.Size = New Point(200, 90)
Dim lbl1 As New Label()
lbl1.Location = New Point(10, 10)
lbl1.Text = "Yoer.vb"
lbl1.AutoSize = True
lbl1.Location = New Point(120, 50)
lbl1.Dock = DockStyle.Top
'' dynamicTableLayoutPanel.Padding = New Padding(2, 17, 4, 5)
dynamicTableLayoutPanel.Controls.Add(lbl1, 0, 0)
dynamicTableLayoutPanel.Controls.Add(textBox2, 1, 0)
Me.dynamicTableLayoutPanel.SetColumnSpan(textBox2, 5)
If you mean you want the table to size to the controls within it, then:
dynamicTableLayoutPanel.AutoSize = True
I know this is old, but I stumbled across it and figured I'd throw my 2 cents in in case someone else comes along.
Note: I'm using Visual Studio 2015 with .NET 4.6. Functionality may differ between versions.
The problem is that the really long text is not word-wrapping to fit within the table or form. Instead, it is set to Dock = DockStyle.Top. This will cause it to make a single line that continues on and gets clipped, similar to a single-line textbox.
If you want it to automatically word wrap, you'll need to use Dock = DockStyle.Fill. Now, this doesn't completely resolve the problem if your row or table isn't large enough to display the text. Since all of the rows are set to AutoSize, it will only do the bare minimum to fit the control vertically. It doesn't care if text gets clipped off. The end result, using your example code against a 6-column, 10-row table, is this:
Since there isn't a word wrap property, you'll need to manually fit it. Now, to do this, you'll need to change the row to be Absolute instead of AutoSize. To figure out how big to make it, you can pretty much rely on PreferredSize. This reveals a much wider Width than the existing regular Width. From that, we can determine how many lines it would take if we wrap it.
This is what my code ended up looking like:
Dim h As Single = 0
Dim chk As New CheckBox()
chk.Text = "You forgot to add the ColumnStyles. Do this on a sample form first with the designer. Click the Show All Files icon in the Solution Explorer window. Open the node next to the form and double-click the Designer.vb file. "
chk.AutoSize = True
chk.Dock = DockStyle.Fill
Dim lbl1 As New Label()
lbl1.Text = "Yoer.vb"
lbl1.AutoSize = True
lbl1.Dock = DockStyle.Top
dynamicTableLayoutPanel.Controls.Add(lbl1, 0, 0)
dynamicTableLayoutPanel.Controls.Add(chk, 1, 0)
dynamicTableLayoutPanel.SetColumnSpan(chk, 5)
' Find the preferred width, divide by actual, and round up.
' This will be how many lines it should take.
h = Math.Ceiling(chk.PreferredSize.Width / chk.Width)
' Multiply the number of lines by the current height.
h = (h * chk.PreferredSize.Height)
' Absolute size the parent row to match this new height.
dynamicTableLayoutPanel.RowStyles.Item(0) = New RowStyle(SizeType.Absolute, h)
The changes included delaring a height variable, renaming the CheckBox variable, setting its Dock to Fill, removing the Location from lbl1, and adding in size calculation. The output:
This isn't perfect since the height includes the checkbox itself, and the checkbox takes up padding, so there can be too much or too little height calculated. There are other calculations that may need to be considered. But, this is a starting point.
A row, in a data table, iscalled FirstImage contains a url to an image file on a web server. I am trying to bind the data of this row to the image source of the picture box.
My current code:
For Each row As DataRow In ListData.Rows
Dim ImageDecode = ser.Deserialize(Of PropertyImage())(row("Images"))
row("FirstImage") = "http://rental.joshblease.co.uk/propertyimages/" & ImageDecode(0).Image
'Returns http://rental.joshblease.co.uk/propertyimages/image1.jpg
Next row
TxtListName.DataBindings.Add("Text", ListData, "Name")
TxtListSlug.DataBindings.Add("Text", ListData, "Slug")
TxtListCreated.DataBindings.Add("Text", ListData, "Created")
ImgListItem.DataBindings.Add("Image", ListData, "FirstImage", True)
DataRepeater1.DataSource = ListData
But at the moment, the image is still blank. I have tried entering the location into a hidden textbox and copying the data over, but I can;t figure out how to use the controls in a data repeater.
This was the experimental copy from a hidden text box code:
If Me.DataRepeater1.ItemCount > 0 Then
Dim n As Integer = Me.DataRepeater1.ItemCount
For i As Integer = 1 To n
Me.DataRepeater1.CurrentItemIndex = i - 1
Dim item = Me.DataRepeater1.CurrentItem
item.Controls("ImgListItem").ImageLocation = item.Controls("TxtImageLocation").Text
Next
End If
Simply add Picture Box property ImageLocation
ImgListItem.DataBindings.Add("ImageLocation", ListData, "FirstImage", True)
The databinding for the image expects binary image data and in this case your passing it a string. What we can do is convert the image location into a format the binding can understand. Take a look at this link C# Code Snippet - Download Image from URL. Then once you have the image in memory, you will be able to bind it to your PictureBox.
Also, keep in mind that the simplest way shown in this answer would not work for you since URIs are not supported by the BitMap class.