How can I save the content of a rich text box even when the form closes? - vb.net

This is my first post here, so please don't judge me if I write something wrong ^^
Anyways, I've recently run into an issue with richtextboxes in Visual Basic .NET and WinForms.
Let's say I have a Main form and a Log form. The log form contains a richtextbox which functions as a log. From the main form I'm writing text to the log and I also format the lines, so they have different colors (blue for information, red for error).
Unfortunately, whenever I close and reopen the log form all text that has been written to it is lost.
I've tried saving it to a text file, but that doesn't save the colors of the text.
Is there any way I can save the text and the colors of the lines even when the form closes?

Here's what the excellent suggestion from Shrotter might look like:
Public Class Form1
Private RtfPath As String
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim folder As String = System.IO.Path.GetDirectoryName(Application.ExecutablePath)
RtfPath = System.IO.Path.Combine(folder, "RtbData.rtf")
If System.IO.File.Exists(RtfPath) Then
RichTextBox1.LoadFile(RtfPath)
End If
End Sub
Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
RichTextBox1.SaveFile(RtfPath)
End Sub
End Class
Of course, you should always wrap the loading/saving of the file in a Try/Catch block in case anything goes wrong.

Related

Saving a setting to MySettings and exiting the program isn't working

I'm having a problem with saving a setting to My Project and then exiting my program with an 'End' statement. If I save the setting but don't execute the end statement, everything works. If I save the setting and then execute the 'End', the setting doesn't get saved. Here's some code that illustrates the problem:
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'reads the last setting correctly
TextBox1.Text = My.Settings.MySetting
End Sub
Private Sub btnWrite_Click(sender As Object, e As EventArgs) Handles btnWrite.Click
'write value, don't exit; works
My.Settings.MySetting = TextBox1.Text
End Sub
Private Sub btnWriteEnd_Click(sender As Object, e As EventArgs) Handles btnWriteEnd.Click
'write value and end; fails
My.Settings.MySetting = TextBox1.Text
End
End Sub
End Class
When I execute the code, whatever was last in My.Settings.MySetting appears in TextBox1. If I change the text in the textbox and click on the 'Write' button and manually exit the program by clicking on the 'X', the new text appears properly changed when I execute the program again. If I change the text and exit programmatically by clicking on 'WriteEnd', the changed setting text doesn't get written to 'MySetting'.
What am I doing wrong?
Thanks
Settings will be saved automatically at shutdown by default, so there's generally no need to call Save. End is definitely the issue. NEVER use End. Call Close on the startup form or call Application.Exit. I compare End with a bouncer grabbing someone by the scruff of the neck and throwing them out, spilling their drink on everyone and leaving their jacket behind, rather than asking them to leave of their own accord.

userform with webview-element doesn't load, program freezes

I'm new to using Visual Studio as well as Visual Basic and still struggle with getting anything to run. The only experience I have is from working with VBA in Excel.
My goal was to create a Userform which links me to frequently used webpages, without using my usually used browser.
Because I need the form to show a webplayer, which does not support internet explorer in any version, the webbrowser-windows form doesn't suit my needs.
I did however find out that there is a webview-windows form which uses the edge-rendering engine and should load the webplayer correctly.
I have a start-page as a userform with two buttons. Number one opens a second window with a webbrowser-form.
Number two is supposed to upen a window with a webview-form.
While The webbrowser-form is loaded correctly, whenever I press button number 2 the program freezes and no userform is shown.
Any idea what I could try?
Thank you in advance,
Alex
PS: Did not do much of coding, just
Public Class Form1
Private Sub btnClickThis_Click(sender As Object, e As EventArgs) Handles btnClickThis.Click
Form2.Show()
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Form3.Show()
End Sub
End Class
on the first userform, to load the userform 3, which contains the webview.
Userform 3 just has this on it.
Public Class Form3
Private Sub Form3_Shown(sender As Object, e As EventArgs) Handles Me.Shown
WebViewCompatible1.Navigate("https://google.de/")
End Sub
End Class

VB.net PrintForm Not Working in New Thread

I am developing a e-filing app and I need to print an adhesive label with some info to attach to the physical folder.
I already designed the label as a Form put the logo and everything that I need there. Then on the Form.Shown event I put the command to print:
Me.PrintLabelForm.Print() (This is VisualStudio PowerPack Control)
And here is where I bump into a problem. The print out is totally empty (I already changed margins setup the printer, etc). The issue is that the form is not actually fully loaded, I switch the method to the print preview and the controls are there but they are empty.
I tried several approaches but I have been not able to do this automatically. One solution that I found was to have a button to do the Me.PrintLabelForm.Print() then it works because the form is already fully loaded and displayed but this is not an option. I need the form to open automatically, print and close.
An option that I think it should work will be to have a new thread with a timer then printing so I did this:
Private Sub LabelPrint_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub LabelPrint_Shown(sender As Object, e As EventArgs) Handles Me.Shown
PrintLabelForm.PrinterSettings.DefaultPageSettings.Margins.Left = 0.1
PrintLabelForm.PrinterSettings.DefaultPageSettings.Margins.Right = 0.1
PrintLabelForm.PrinterSettings.DefaultPageSettings.Margins.Top = 0.1
PrintLabelForm.PrinterSettings.DefaultPageSettings.Margins.Bottom = 0.1
PrintLabelForm.PrinterSettings.DefaultPageSettings.Landscape = True
Dim PrintThread As New System.Threading.Thread(AddressOf PrintSub)
PrintThread.Start()
End Sub
Private Sub PrintSub()
Threading.Thread.Sleep(1000)
Me.PrintLabelForm.Print()
Me.Close()
End Sub
The idea was to have the PrintSub to give the app enough time to finish to render the whole thing then print but I am getting this error:
**An unhandled exception of type 'System.Exception' occurred in Microsoft.VisualBasic.PowerPacks.dll
Additional information: The window being printed must be visible and contain focus.**
So I wonder how to make this thread have the window form in focus in order to be able to print.
That is all. Thanks for all the help.
Always work with the form only from main thread.
You found it right – form printing will not run from new thread.
When you do any actions on forms, you must perform all the work from Dispatcher thread. It is the thread on which all event methods run. If you fail doing so, you can encounter many side effects. (Not only problem with printing. I've been there and this advice from senior Windows programmer helped me to get things back to normal.) So do not use form printing from any other thread.
If you want a workaround for this, print form to the image (in main thread) and then you can print the image using new thread.
This has nothing to do with .NET, this is related to internals of Windows Forms technology. Welcome to Windows programming.
I manage to solve it putting this line in the Form.Shown
PrintLabelForm.Print(Me, PrintForm.PrintOption.ClientAreaOnly)
I don't know why or how but it works.
Thanks to all of you guys for your help. Let's hope I don't find myself trying to do stuff when the form is fully displayed.
This is my full code let's hope it works for someone else:
Imports Microsoft.VisualBasic.PowerPacks.Printing
Public Class PrintAdhesiveLabel
Private Sub LabelPrint_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub LabelPrint_Shown(sender As Object, e As EventArgs) Handles Me.Shown
PrintLabelForm.PrinterSettings.DefaultPageSettings.Margins.Left = 0.1
PrintLabelForm.PrinterSettings.DefaultPageSettings.Margins.Right = 0.1
PrintLabelForm.PrinterSettings.DefaultPageSettings.Margins.Top = 0.1
PrintLabelForm.PrinterSettings.DefaultPageSettings.Margins.Bottom = 0.1
PrintLabelForm.PrinterSettings.DefaultPageSettings.Landscape = True
PrintLabelForm.Print(Me, PrintForm.PrintOption.ClientAreaOnly)
Me.Close()
End Sub
End Class
Perhaps this is relevant:
Only the form that currently has focus can be printed by using this
method. If you have set the Form property to another form before
calling this method, the image of the form may not be rendered as
expected. To avoid this, call the Focus method of the form before you
call Print.
So call Me.PrintLabelForm.Focus() before calling Me.PrintLabelForm.Print():
Private Sub PrintSub()
Threading.Thread.Sleep(1000)
Me.PrintLabelForm.Focus()
Me.PrintLabelForm.Print()
Me.Close()
End Sub

VB.net, Being able to select text in a richtextbox without losing focus?

VB.net .. Currently I have two controls, one richtextbox and a textbox. The RTB is readonly, and also HideSelection is set to false.
The textbox is generic, it allows for input (to send data).
I want to be able to select things in the richtextbox without losing focus in the textbox. There is a client called 'mushclient' that does this, and it works pretty well. The text is still selected, but it doesn't lose the focus on the chatbar to type in.
I don't exactly know however how to prevent 'focus' though. At the moment it breaks flow when you are in game but want to copy something, you'll have to click the textbox again to start typing again. I understand I could setfocus after clicking the RTB, but this feels overall a bit odd. I was wondering if there is a more elegant solution.
Thanks!
This seems to work well for me. The TextBox does loose focus, but as soon as the Mouse_UP event fires, the selected text is copied to the clipboard and focus is sent back to the text box.
Public Class Form1
Dim LostFocusControl As Control
Private Sub RichTextBox1_MouseUp(sender As Object, e As MouseEventArgs) Handles RichTextBox1.MouseUp
If RichTextBox1.SelectedText.Length > 0 Then
Clipboard.SetText(RichTextBox1.SelectedText)
End If
If Not IsNothing(LostFocusControl) Then
LostFocusControl.Focus()
End If
End Sub
Private Sub ControlLostFocus(sender As Object, e As EventArgs) Handles TextBox1.LostFocus
LostFocusControl = Sender
End Sub
End Class
The code is a bit longer than it could be, but this makes it easier if later on you want to change the control that focus is returned to. To change the control that you want to return focus to, just change the name of the control that the handler is subscribed to e.g
Change
Private Sub ControlLostFocus(sender As Object, e As EventArgs) Handles TextBox1.LostFocus
To
Private Sub ControlLostFocus(sender As Object, e As EventArgs) Handles Listbox1.LostFocus
or whatever the name of the control is that you want to return focus to.

Display a modeless Form but only one

VB2010. I must be missing something because I couldn't find a solution after searching for an hour. What I want to do is simple. In my app I want to display a modeless form so that it is floating while the user can still interact with the main form.
dim f as New frmColors
f.Show(Me)
But I only want one instance of the form at any time. So how can I prevent more than once instance being displayed, and if there is one instance then just give it focus?
Does something like this work for you, if the form is already visible you can not do a Show, you can just do a BringToFront, also you can check to see if the Form has been disposed so you can New up another one.
Public Class Form1
Dim f As New frmColors
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
If f.IsDisposed Then f = New frmColors 'To handle user closing form
CheckForm(f)
End Sub
Private Sub CheckForm(frm As Form)
If frm.Visible Then
frm.BringToFront()
Else
frm.Show(Me)
End If
End Sub
End Class
Make your form follow the singleton pattern. I can't vouch for this sample, but from the text it appears to do what you want.