vb.net textbox / richtextbox GetPreferredSize not working - vb.net

I have a winforms RichTextBox and TextBox (trying both). As I type text, I want the box to get bigger vertically (or smaller vertically) so that all the text is viewable.
I am using the following code in the RichTextBox TextChanged event:
RTB.Height = RTB.GetPreferredSize(New Size(RTB.Width, 0)).Height
This code works in most situations apart from one - when you put in a single word (without spaces) which is larger than the width of the box. Any ideas?
Thanks.

Found the following answer already on Stackoverflow! Just had to search better ...
Private Sub rtb_ContentsResized(ByVal sender As Object, ByVal e As System.Windows.Forms.ContentsResizedEventArgs) Handles txtQuestion.ContentsResized
Dim h = e.NewRectangle.Height, w = e.NewRectangle.Width
h = Math.Max(h, sender.Font.Height)
h = Math.Min(h, Me.ClientSize.Height - 10 - sender.Top)
h += sender.Height - sender.ClientSize.Height + 1
sender.Height = h
End Sub
from
Measure String inside RichTextBox Control

Try experimenting with the RTB min and max size properties.
Sounds like setting a max width may address your issue.

Related

Programatically positioning a control in a VB.net user control

I have a user control in VB.Net VS2019. It is used to display a description, a value and units. It generally works if the description is not too large.
The controls in the user control are all labels.
In the resize event it sizes the descriptions width to 66% of the overall width, 22% for the value, and whatever is left over for the units.
Then it set the description's left to 0, the value's left to the width of the description (plus a little). For the unit's position, it adds the left position of the value plus its width and a little.
But when the program runs the controls overlap each other and do not take the entire space of the UserControl.
For example the UserControl is 236 wide, but it looks like everything is squished to about 1/2 or 2/3s.
I have set Anchor to none and docking to none.
I perform these calculations in the 'Resize' event as shown below. The code was ported from an old VB6 program.
Is the 'Auto' size property taking precedence over the width I specify?
Private Sub UserControl1_Resize(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles MyBase.Resize
Dim lblUnits_Size As Integer
Label1.Height = MyBase.Height
Label2.Height = MyBase.Height
lblUnits.Height = MyBase.Height
Label1.Width = CInt(MyBase.Width * 0.6167)
Label2.Width = CInt(MyBase.Width * 0.22)
' I want the width of the units to be whatever is left over
lblUnits_Size = MyBase.Width - (Label1.Width + Label2.Width) - 6
If lblUnits_Size <= 0 Then lblUnits_Size = 1
lblUnits.Width = lblUnits_Size ' was -> TwipsToPixelsX(lbUnits_Size)
Label1.Left = 0
Label2.Left = (Label1.Left + Label1.Width) + 3
lblUnits.Left = (Label2.Left + Label2.Width) + 3
End Sub
I found it, the resize code needs to be called after the description changes. I guess ole VB6 did this automatically or someway the resize's were called after.

Multiple textboxes with selection or focus to follow in a multiline textBox?

I have a problem with a multiline TextBox text box, which when searching for a character string, stays with its first focus on the word in the first location, but still continues to select the other words by not selecting them not !
Here is my code:
If testArray(p) / 2987 >= dub + (1787 / 2987) And testArray(p) / 2987 < dub + 1 Then
Main.TextBox31.Focus()
Main.TextBox31.SelectionStart = Main.TextBox31.Text.IndexOf(Me.TextBox1.Text)
Main.TextBox31.SelectionLength = Me.TextBox1.TextLength
Main.TextBox31.ScrollToCaret()
MsgBox("oui16")
System.Threading.Thread.Sleep(1000)
End If
The first line gives me the position of the search bytes. The TextBox31 control is the multiline control, in which I have the search bytes in the testArray (p) array. The TextBox1 control gives me the string I'm looking for.
PS:
I was able to achieve something like this with a listbox, it might translate over to textboxes too?
Dim rect As Rectangle
Dim bruh As New SolidBrush(Color.FromArgb(120, 0, 0, 225))
Dim gfx As Graphics = ListBox1.CreateGraphics
gfx.FillRectangle(bruh, rect)

How can I dynamically change record textbox hieghts in my report to the same as the highest for each record?

I have a report with two fields (txtQuestion & txtLookingFor) which is populated via a query. Sometimes txtQuestion is much longer than txtLookingFor (or vice versa) and I want the printed report to appear even, by making the shorter of the two equal in height to the longer of the two - for each record on this report.
I have some VBA which is triggered by even "Detail OnFormat" which is supposed to retrive the "height" values of each of the text boxes, find the maximum, and set both heights to this value. I cannot seem to get (read) the height values (from each record). But I can manually set the height values (per record) to some arbitrary value via VBA if I want.
I have tried all the "Can Grow" and "Can Shrink" options. My text boxes do grow to their own height (per record), but I cannot seem to read what that value is, for use in my VBA code.
Private Sub Detail_Format(Cancel As Integer, FormatCount As Integer)
maxheight = 100
If (Me.txtQuestion.Height > maxheight) Then
maxheight = Me.txtQuestion.Height
End If
If (Me.txtLookingFor.Height > maxheight) Then
maxheight = Me.txtLookingFor.Height
End If
Me.txtQuestion.Height = maxheight
Me.txtLookingFor.Height = maxheight
Me.txtNotes.Height = maxheight
End Sub
Here's some code I found on tek-tips that gives a general idea of how to make textboxes look the same height by drawing rectangles around them. The controls themselves are not resizable.
Private Sub Detail_Print(Cancel As Integer, PrintCount As Integer)
Dim intMaxHeight As Integer
Dim ctl As Control
'Find highest control in Detail section that has a tag property of "Border"
For Each ctl In Me.Section(0).Controls
If ctl.Tag = "Border" Then
If ctl.Height > intMaxHeight Then
intMaxHeight = ctl.Height
End If
End If
Next
'Draw a box around each control in Detail that has a tag property of "Border"
For Each ctl In Me.Section(0).Controls
If ctl.Tag = "Border" Then
Me.Line (ctl.Left, ctl.Top) - Step(ctl.Width, intMaxHeight), vbBlack, B
End If
Next
End Sub
Reference:
https://www.tek-tips.com/viewthread.cfm?qid=1676341

Picturebox will not display image

I'm writing a program that will create and load pictureboxs at run time. The problem is that they will not show up or display anything. Not sure what i'm doing wrong. i have checked and the full path for the images are correct.
Sub DrawScreen()
'Call g.DrawImage to draw whatever you want in here
Dim layers(Me.ListBox1.Items.Count) As PictureBox
For i = 0 To ListBox1.Items.Count - 1
'Create New Layer as picturebox
layers(i) = New PictureBox
layers(i).Parent = Me.picWatch
layers(i).BackColor = Color.Transparent
layers(i).Visible = True
Select Case ListBox1.Items(i)
Case "image"
'Debug.Print(ListofLayers(i).Full_Path)
layers(i).Image = Image.FromFile(ListofLayers(i).Full_Path)
layers(i).Top = ListofLayers(i).X
picWatch.Controls.Add(layers(i))
Case "shape"
'Dim g As Graphics
'g.DrawRectangle()
Case "text"
Dim g As Graphics = layers(i).CreateGraphics
g.DrawString(ListofLayers(i).Text, New Font("Arial", 12), Brushes.White, ListofLayers(i).X, ListofLayers(i).Y)
Case Else
Debug.Print(ListBox1.Items(i))
End Select
Next
Me.Refresh()
End Sub
You never add the picture boxes to the form. Call Me.Controls.Add():
Me.Controls.Add(layers(i))
And as already pointed out by LarsTech:
You seem to have a typo here:
layers(i).Top = ListofLayers(i).X
X is the coordinate for the control's horizontal position and is the same as .Left.
Y however is the coordinate for the control's vertical position, which is the same as .Top.
Using CreateGraphics is a bad idea. For starters, what you draw with it will get removed when the control is redrawn. And since you're not disposing it you'll also have memory leaks.
Subscribe to the Paint event for each picture box instead and do all drawing in there.
Finally, just a little note: Array declarations in VB.NET does not specify how many items there are to be in the array, but to what index the array should end at. And since arrays are zero-based, this:
Dim layers(Me.ListBox1.Items.Count) As PictureBox
...is equal to this:
Dim layers(0 To Me.ListBox1.Items.Count) As PictureBox
Thus the array will contain ListBox1.Items.Count plus one since what's inside the parentheses merely specify the lower and/or upper bound.
To create an array with the "correct" amount of items you should always specify the size minus one:
Dim layers(Me.ListBox1.Items.Count - 1) As PictureBox

Have CustomListView resize last column to fit width

I have a custom list view control in WinForms that applies some custom styles. This works well, however I have a part of the control that is not covered when the user maximises the screen (columns are set to fixed width) and ColumnHeaderAutoResizeStyle.None is set. I'd like to have the last column auto fill the gap.
To achieve this inside of the custom control I have added the following code to ListView.SizeChanged event.
Private Sub CustomListView_Resized(sender As Object, e As EventArgs) Handles Me.SizeChanged
Try
If (Not _isResizing) Then
_isResizing = True
Dim myListView As customListView = DirectCast(sender, customListView)
' Work out current column widths
Dim totalColumWidthInPx As Integer = 0
For i = 1 To Columns.Count - 1
totalColumWidthInPx += Me.Columns(i).Width
Next
' Increment the final column by the difference in width to make up the gap
Me.Columns.Item(Columns.Count - 1).Width += (myListView.ClientRectangle.Width - totalColumWidthInPx)
End If
Finally
_isResizing = False
End Try
End Sub
This is always giving me inconsistent results, the column width is incremented to much and adds the scrollbars as below.
Little bit of debug info.
Control: lvAppointments, Width (px): 701, Client Rectangle Width (px):
697, All Column Widths: 648, Diff: 49, Last Column: 234, Last Column +
Diff: 283