Font Family and Font Size Combo Box Coding Bugs - vb.net

it's been a while since I posted. Haven't had much time for programming for a while. Just got back into it a couple of days ago. I'm working on a personal project which is a kind of Project Manager with a fairly complete text editor. I am working with VB.NET in the Visual Studio IDE. I have been trying to mimic the behaviour of Word and other editors as follows:
FONT FAMILY: This code actually works to change the Font Family in the Font Picker Combo Box in real time according to text formatting at cursor position. i.e. click on different text formats in the Rich Text Box and the Font Family is displayed in the Combo Box! I am using a Tool Strip Combo Box!
BUG: The Font Family code (i.e. penultimate snippet) removes the formatting from text when it is reselected after formatting?
FONT SIZE: This code changes the Font Size in the Font Size Combo Box when Ctrl+Shift+< OR Ctrl+Shift+> keyboard shortcuts are used.
BUG: The Font Size code (i.e. Last snippet) affects Font Size when using the ,.<> keys because these keys are configured in the code to alter the value of the Font size in the Font Size ComboBox. So, pressing the keys causes the Font Size in the Combo Box to increase or decrease which also means the font in the RTB increases or decreases?!
WHAT I NEED: 1. Selecting formatted text should not remove formatting, but Font Family should be displayed in Combo Box according to formatting in the RTB. 2. The Font Size Combo Box value should only be altered when I use the keyboard shortcuts, Ctrl+Shift+< OR Ctrl+Shift+> to display the true Font Size in real time. Using the current code increments/reduces in steps of 2 rather than one Font Size at a time??? I realize this code is fairly simple and understand roughly why it's not working, but I can't seem to find a way to fix the issue? Any help would be greatly appreciated!
WHAT I HAVE TRIED
Rich Text Box (i.e. RTB = Description):
FONT FAMILY COMBO BOX CODE: (uses a timer)
Private Sub tbSelectFont_SelectedIndexChanged(sender As Object, e As EventArgs) Handles tbSelectFont.SelectedIndexChanged
Dim NewFont As New Font(tbSelectFont.SelectedItem.ToString(),
Description.SelectionFont.Size,
Description.SelectionFont.Style)
Description.SelectionFont = NewFont
End Sub
FONT SIZE COMBO BOX CODE:
Private Sub tbSelectSize_SelectedIndexChanged(sender As Object, e As EventArgs) Handles tbSelectSize.SelectedIndexChanged
Dim NewSize As Single = tbSelectSize.SelectedItem
Dim NewFont As New Font(Description.SelectionFont.Name, NewSize, Description.SelectionFont.Style)
Description.SelectionFont = NewFont
End Sub
RELATED FORM LOAD EVENTS:
'Display Installed Fonts In Font Picker (tbSelectFont):
Dim fonts As New InstalledFontCollection()
For fntFamily As Integer = 0 To fonts.Families.Length - 1
tbSelectFont.Items.Add(fonts.Families(fntFamily).Name)
Next
'Display Font Size in Font Size Picker:
For fntSize = 10 To 75
tbSelectSize.Items.Add(fntSize)
Next
FONT FAMILY:
Private Sub Description_SelectionChanged(sender As Object, e As EventArgs) Handles Description.SelectionChanged
If Description.SelectionFont IsNot Nothing Then
Dim fontSize As Single = Description.SelectionFont.Size
tbSelectSize.Text = fontSize
tbSelectFont.Text = Description.SelectionFont.Name
End If
End Sub
FONT SIZE:
If (Keys.Control AndAlso Keys.Shift AndAlso e.KeyCode = Keys.Oemcomma) Then
tbSelectSize.Text -= 1
ElseIf (Keys.Control AndAlso Keys.Shift AndAlso e.KeyCode = Keys.OemPeriod) Then
tbSelectSize.Text += 1
End If
OTHER CODE I TRIED:
THIS CODE WORKS, BUT WHEN YOU SELECT FORMATTED TEXT IT THROWS AN EXCEPTION OR REMOVES FORMATTING: System.NullReferenceException: 'Object reference not set to an instance of an object.'
SOURCE: MY OWN COMMENT FROM:
how to get the fontsize of a certain line in a richtextbox in c# using winforms
Dim fontName As String = Description.SelectionFont.Name
Dim fontSize As Single = Description.SelectionFont.Size
tbSelectFont.Text = fontName
tbSelectSize.Text = fontSize
tbSelectFont.SelectedIndex = tbSelectFont.FindStringExact(Description.SelectionFont.Name)
tbSelectSize.SelectedIndex = tbSelectSize.FindStringExact(Description.SelectionFont.Size)
THIS CODE WORKS, BUT WHEN YOU SELECT FORMATTED TEXT IT THROWS AN EXCEPTION: System.NullReferenceException: 'Object reference not set to an instance of an object.'
SOURCE: how to get the fontsize of a certain line in a richtextbox in c# using winforms - MarkusEgle's solution.
Dim comboBox1Index As Integer = tbSelectFont.FindStringExact(Description.SelectionFont.Name)
Dim comboBox2Index As Integer = tbSelectSize.FindStringExact(Description.SelectionFont.Size.ToString())
tbSelectFont.SelectedIndex = comboBox1Index
tbSelectSize.SelectedIndex = comboBox2Index

Related

How do I change the fontstyle to bold on a font I already created as regular

I am allowing the use of themes in my application. So I create a font based on the user's choice of themes. However, I need to change the fontstyle from regular to bold, but I don't want to have to recreate the font.
I am doing it this way, because not all users will have the font installed on their machine. So I am embedding the font into the application.
For example: I may have a textbox assigned the font like this:
txtbox.font = theme_font
Is there a way to simply change the style to bold?
txtbox.font = theme_font.fontstyle.bold ' <-- this doesn't work
I call the font creation subroutine like this:
Public Shared theme_font = BerlinSans.GetInstance(theme_font_size, FontStyle.Regular)
And this is the subroutine being called:
Module BerlinSans
'PRIVATE FONT COLLECTION TO HOLD THE DYNAMIC FONT
Private _pfc As PrivateFontCollection = Nothing
Public ReadOnly Property GetInstance(ByVal Size As Single, ByVal style As FontStyle) As Font
Get
'IF THIS IS THE FIRST TIME GETTING AN INSTANCE
'LOAD THE FONT FROM RESOURCES
If _pfc Is Nothing Then LoadFont()
'RETURN A NEW FONT OBJECT BASED ON THE SIZE AND STYLE PASSED IN
Return New Font(_pfc.Families(0), Size, style)
End Get
End Property
Private Sub LoadFont()
Try
'INIT THE FONT COLLECTION
_pfc = New PrivateFontCollection
'LOAD MEMORY POINTER FOR FONT RESOURCE
Dim fontMemPointer As IntPtr = Marshal.AllocCoTaskMem(My.Resources.BRLNSR.Length)
'COPY THE DATA TO THE MEMORY LOCATION
Marshal.Copy(My.Resources.BRLNSR, 0, fontMemPointer, My.Resources.BRLNSR.Length)
'LOAD THE MEMORY FONT INTO THE PRIVATE FONT COLLECTION
_pfc.AddMemoryFont(fontMemPointer, My.Resources.BRLNSR.Length)
'FREE UNSAFE MEMORY
Marshal.FreeCoTaskMem(fontMemPointer)
Catch ex As Exception
'ERROR LOADING FONT. HANDLE EXCEPTION HERE
End Try
End Sub
End Module
You can use the Font(Font, FontStyle) constructor. Just pass it the old font and the new style you want to use and it'll copy the properties from the old font into the new one for you (apart from the style, of course).
txtbox.Font = New Font(theme_font, FontStyle.Bold)

Vb.Net: Limit the total width of characters entered into a textbox?

Let me be very clear - I am not looking for a static character limit here (Textbox.MaxLength just doesn't cut it.)
I'm making a simple messaging program and I'd like to implement a character limit. The messages are displayed inside a listbox and can't be horizontally scrolled/wrapped. The solution: impose a limit on every message so that users don't accidentally cut off their own messages.
The problem is that 10 small characters are a lot smaller than 10 full width characters. - E.G. i and W:
iiiiiiiiii
WWWWWWWWWW
I'd like to find a way to limit the characters entered into the text box by the actual amount of pixels the string is wide.
so that:
nobody can use all capitals and get cut off, and
nobody can type normally and be stopped by the character limit far earlier than neccesary.
For reference, I'm using Verdana 8.25pt for the listbox.
Any suggestions would be appreciated,
Thanks.
This should do the trick for you. I've deliberately chosen the keyUp event because the user will see the letter typed and it disappearing.
Private Sub TextBox1_TextChanged(sender As Object, e As KeyEventArgs) Handles TextBox1.KeyUp
Dim text1 As String = TextBox1.Text
Dim textboxFont As Font = TextBox1.Font
Dim textSize As Size = TextRenderer.MeasureText(text1, textboxFont)
If textSize.Width > TextBox1.ClientRectangle.Width Then
Dim cursorLocation As Integer = TextBox1.SelectionStart
TextBox1.Text = TextBox1.Text.Remove(cursorLocation - 1, 1)
If cursorLocation > TextBox1.Text.Length Then
TextBox1.SelectionStart = TextBox1.Text.Length
Else
TextBox1.SelectionStart = cursorLocation
End If
End If
End Sub
Basically what is happening is that the text is rendered (not displayed) using the font of the textbox and measured. If the width of the rendered text is greater than the client area of the textbox, the letter is removed at the point it was typed. This can be anywhere in the text box.
If the cursor is at the end of the text when the letter is removed, .net automatically sets the cursor position to the beginning is a letter is removed. So this sub checks if the initial cursor position was a bigger index than the length of the new textbox contents. If so, the cursor is set to the end again. Otherwise it is moved back 1 because a character was deleted.

VB.NET Listbox item color [duplicate]

So I'm trying to make a listbox with 2 buttons.
Listbox is supposed to display files from a specific folder (I get back to this)
And the two buttons are supposed to be called "Set.." (As in set directory)
and Update (As the list will be refreshed (Something I do every time the Windows Form Runs.
So as of now, when I start my application, and go to the form with the listbox, the listbox is empty. When pressing "Update", the List box picks up files from an address located on my Harddrive (So this is a static address located in my code).
It also finds 7 different extensions (Filetypes), and lists all of them correctly.
My problem is as follows, I want the set Button to open a File Dialog for the user on First-Time Runtime, so the user himself can choose what folder the program "Indexes or Searches" if you will. And then when he runs the application again, and finds the listbox, he can only press Update, and the listbox shows the content of the folder he choose last time.
The Set - button doesn't do anything in my code right now.
Second up, I want each filetype to be labeled or colored with a specific color.
Like; .txt should be blue, .jpg is red, ect..
Running Visual Studio 2013 if that helps.
Also, when checking my code, if you have any suggestions too, how I can improve the code, make it easier, shorter, and just to change things to avoid duplicate codes, please let me know.
Here is from the Design in VS2013
Code:
Private Sub Form_Load(sender As Object, e As EventArgs) Handles Me.Load
FolderBrowserDialog1.SelectedPath = "xxx\xxx\xxx\xxx"
System.IO.Directory.GetCurrentDirectory()
Private Sub updateButtonGame_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles updateButtonGame.Click
If FolderBrowserDialog1.SelectedPath = "xxx\xxx\xxx\xxx" Then
ListFiles(FolderBrowserDialog1.SelectedPath)
End If
End Sub
Private Sub ListFiles(ByVal folderPath As String)
filesListBox.Items.Clear()
Dim fi = From f In New IO.DirectoryInfo(FolderBrowserDialog1.SelectedPath).GetFiles().Cast(Of IO.FileInfo)() _
Where f.Extension = ".z64" OrElse f.Extension = ".nds" OrElse f.Extension = ".BIN" OrElse f.Extension = ".smc" OrElse f.Extension = ".ISO" OrElse f.Extension = ".nes" OrElse f.Extension = ".gb"
Order By f.Extension
Select f
For Each fileInfo As System.IO.FileInfo In fi
filesListBox.Items.Add(fileInfo.Name)
Next
End Sub
Another thing, this is more optional..
My list is completely black, so I choose to have the "Items" in the Listbox turn Light gray.
I played around with something called e.Graphics in hope to achieve Coloring a specific filetype, and it turned ALL items either Black, Red, or whatever I put it to.
But after removing the code, all Items turns into the same color as the Background color of the Listbox. So I can no longer see the elements actually being there, other than the Scroll-bar popping up on the side (Since its many Items in the folder I picked)
Also, I am not that good with coding/visual studio yet, as I started around 1 week ago to date.
Started with VB 2010 and then went to VS2013 to see if I managed to fix some issues, also related to List Box.
If I explained rather poorly, let me know and I'll update with better info.
Project was also first created in VB 2010, and then "Migrated" or opened in VS 2013.
A much, much better way to do this is with a ListView and an ImageList with some standard images for Text, Image, PDF etc in the list, then just set the image key for each item when you add them to the list.
Alternatively, you could emulate the same thing in a listbox (using OwnerDrawFixed) to draw a specified image to indicate the file type. A really good way to implement this is as an ExtenderProvider using code similar to that below as a starting point. As an EP, you can link any cbo or listbox to an image list to provide image cues very much like the ListView works:
The reason you do not see your colored item idiom very often is that whatever colors you pick will not look right on all systems. The more colors, the more likely and more often they wont have enough contrast, be readable etc with the user's color scheme. You also dont need a "Legend" to explain what the colors mean - an image is self explanatory. That said, the DrawItem code would be something like this:
NB: Listbox control is set to OwnerDrawFixed, ItemHeight = 16
Private Sub lb_DrawItem(sender As Object,
e As DrawItemEventArgs) Handles lb.DrawItem
Dim TXT As Color = Color.Black
Dim JPG As Color = Color.Green
Dim PDF As Color = Color.Blue
Dim EXE As Color = Color.Gray
Dim SEL As Color = SystemColors.HighlightText
Dim thisColor As Color = Color.Orange
Dim ndx As Integer = e.Index
' isolate ext ans text to draw
Dim text As String = lb.Items(ndx).ToString()
Dim ext As String = System.IO.Path.GetExtension(text).ToLowerInvariant
' dont do anything if no item being drawn
If ndx = -1 Then Exit Sub
' default
e.DrawBackground()
' color selector
Select Case ext
Case ".jpg"
thisColor = JPG
Case ".txt"
thisColor = TXT
Case ".exe"
thisColor = EXE
Case ".pdf"
thisColor = PDF
End Select
' override color to use default when selected
If (e.State And DrawItemState.Selected) = DrawItemState.Selected Then
thisColor = SEL
End If
' render the text
TextRenderer.DrawText(e.Graphics, text, lb.Font, e.Bounds,
thisColor, TextFormatFlags.Left)
' default
e.DrawFocusRectangle()
End Sub
Result:
Works on My SystemTM

Adapt label width to text

I basically programmatically generate many labels with a text read from a text file so I would like to know how I can programmatically adapt the width of a Label to its text.
Controls come in two flavors. The ActiveX version of a label has an AutoSize property. For example, with a ActiveX label control named Label1 in Sheet1
Private Sub test()
Sheet1.Label1.WordWrap = False
Sheet1.Label1.AutoSize = True
Sheet1.Label1.Caption = "This is a lot of text to put in a label"
End Sub
will automatically adjust the width to fit.

VB.NET - RichTextBox - Apply formatting to selected text

I have a RichTextBox control on my form. I also have this button, labeled Bold, that I want, if someone selects text in the RichTextBox, then presses the button, the selected text turns bold. Any way to do that? Simple, everyday task for end users. Thanks.
A variation on the above that takes into consideration switching bold on/off depending on the currently selected text's font info:
With Me.rtbDoc
If .SelectionFont IsNot Nothing Then
Dim currentFont As System.Drawing.Font = .SelectionFont
Dim newFontStyle As System.Drawing.FontStyle
If .SelectionFont.Bold = True Then
newFontStyle = currentFont.Style - Drawing.FontStyle.Bold
Else
newFontStyle = currentFont.Style + Drawing.FontStyle.Bold
End If
.SelectionFont = New Drawing.Font(currentFont.FontFamily, currentFont.Size, newFontStyle)
End If
End With
It may need cleaned up a bit, I pulled this from an older project.
You'll want to use the .SelectionFont property of the RichTextBox and assign it a Font object with the desired styles.
Example - this code would be in the event handler for the button:
Dim bfont As New Font(RichTextBoxFoo.Font, FontStyle.Bold)
RichTextBoxFoo.SelectionFont = bfont