How to Mix Form Fields and Graphics? - vb.net

I am trying to use the circular progress bar solution that was provided at
Visual basic circular progress bar
However I am getting a lot of error messages when I try to incorporate it within a Windows Form that has textbox entries (have to do with System.EventArgs versus PaintEventArgs and MyBase.Load versus Me.Paint).
I tried "mixing" both handles like this:
Private Sub LoginForm1_Load(ByVal sender As System.Object, e As System.EventArgs, g as PaintEventArgs) Handles MyBase.Load, Me.Paint
but of course that bombed out. Can someone please advise what are my alternatives here?
Thanks

You're taking something very easy and making it hard. ALL drawing gets done in the Paint event handler or a method called from the Paint event handler. That's it, that's all when it comes to drawing. You already know how to do that because you already have the code to do it from another question. Use that code.
If the code that does the drawing needs to get data from elsewhere to know what to draw then do that. There's nothing magical about a method using the value of one or more fields to do its work. The data in that field(s) can be put there by any other method, e.g. the Load event handler of the form, the TextChanged event handler of a TextBox or the Click event handler of Button.
Here's a simple example that will draw whatever is in a TextBox as the user types:
Private textToDraw As String
Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.Text
textToDraw = TextBox1.Text
'Force a Paint event to be raised.
Invalidate()
End Sub
Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
e.Graphics.DrawString(textToDraw, Font, Brushes.Black, PointF.Empty)
End Sub
Put the data where it can be accessed, raise a Paint event, do the drawing. Simple!
The main point to note there is that calling Invalidate with no arguments will cause the entire control it's called on (the form, in this case) to be repainted and that should be avoided if possible. You should calculate and specify the smallest area possible that has or could have changed and pass that when calling Invalidate. That way, parts of the control that definitely haven't changed will not be repainted, speeding up the process. You draw everything every time but the actual repainting of pixels on the screen is the slow part of the operation and so should be minimised. You might read this for more information.

Related

All Handles disappeared vb.net

I was working on a project and for no reason all Handles disappeared from the form
For example:
Private Sub Button17_Click(sender As Object, e As EventArgs) Handles Button17.Click
has become
Private Sub Button17_Click(sender As Object, e As EventArgs)
I have a lot of tools in the form
Is there a shortcut to retrieve Handles?
This happens if a control is being cut and pasted back on the form or if it's deleted and recreated with the same name.
To recreate the Handles you can click behind the closing bracket and press SPACE - TAB - SPACE and fill the rest up with the help of IntelliSense.
There's nothing to retrieve. They are just regular methods now. You need to attach them to the appropriate events like you would any other method you wrote yourself. Open the Properties window in the designer and click the Events button. Select a control on the form, click the drop-down for the event of interest and select the correct method.

Prevent old form closing until new form opens

A very basic/simple question with I'm sure, an even simpler answer, but I just cannot figure it out. I have two forms that a user can switch between using the corresponding menu link on each form. I want to be able to keep the previous form visible on screen until the new form is displayed. In it's current state, the form disappears off screen for around 3/4 of a second before the new one is shown and from a UI/design perspective, I'd like this to stay on screen.
I'm currently using the below code to close and open the forms:
form1.Show()
Me.Close()
form2.Show()
Me.Close
I have tried experimenting with ShowDialog() which does seem to keep it on screen on first run, but clicking back into the form a second time says an error message:
System.InvalidOperationException: 'Form that is already visible cannot be displayed as a modal dialog box. Set the form's visible property to false before calling showDialog.'
Is there a simple line of code to achieve what I want here?
If there is some time consuming code in the Form.Load event (for example, if data is being retrieved from a database) then the following code might help.
Private Sub Form2_Shown(sender As Object, e As EventArgs) Handles Me.Shown
'Assuming default instances
Form1.Close()
End Sub
Posting an answer incase there's an inherit reason this is not best practice or to avoid doing this, but using the below sped it up:
Private Sub menu1_Click(sender As Object, e As EventArgs) Handles menu1.Click
form1.Show()
form1.Refresh()
Me.Close()
End Sub
This was inspired by adding in a Application.DoEvents working, so adjusted the code to avoid that dreaded line.

Set Focus to Form After Me.Show

I've come across a peculiar focusing issue. I have created the following "search" program:
It runs in the background.
When you double-tap the Ctrl key it becomes visible.
You can type in the textbox because the form has focus.
If the form loses focus (I click on my desktop, for example), it disappears after 3 seconds.
I double-tap the Ctrl key again, and again it becomes visible.
But this time, no matter what I try, the form is not focused and I cannot type in the textbox without first manually clicking on the form.
What's particularly interesting is that when I run this program in debug mode from Visual Studios, the program regains focus upon double-tapping Ctrl key and becoming visible, and I can immediately start typing in the text box. However, when I build this program and run it alone, the program appears but does not regain focus upon double-tapping Ctrl key, and therefore I cannot type in the text box until I manually click the form.
After Me.Show() I have tried:
Me.Focus()
Me.Validate()
Me.Select()
Textbox1.Select()
Textbox1.Focus()
The form is topmost and normally running in administrator, but the same problem arises regardless.
The issue can be recreated in a more simple manner. Create a form with
Button ("Button1")
TextBox
Two timers ("hideForm", "showForm") both with intervals of 1000
Code:
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
hideForm.Start()
sender.Enabled = False
End Sub
Private Sub hideForm_Tick(sender As Object, e As EventArgs) Handles hideForm.Tick
Me.Hide()
hideForm.Stop()
showForm.Start()
End Sub
Private Sub showForm_Tick(sender As Object, e As EventArgs) Handles showForm.Tick
showForm.Stop()
Me.Show()
Me.Activate()
End Sub
End Class
Click the button, and immediately click on a different window (so the form loses focus). Wait until the form is hidden and shown again. The textbox should have focus. Try typing.
If the program is run in debugging mode in Visual Studios, it works as expected. If you build the program and run it outside of VS, the form will reappear without focus, and you cannot type in the textbox without manually selecting the form.
Sorry for the long-winded explanation. It's a difficult issue to properly describe.
Try the form event handler Activate. Inside that method, you can use setFocus to gain focus for that particular Text Box. I know this answer is too late. But hope this helps someone.
Private Sub Form_Activate()
TextBox1.SetFocus
End Sub
Try an event handler for Form_Activate, and within that handler pass the focus to your textbox.
Instead of Focus, you can also try TextBox1.Select. This SO link provides some additional information and something about the difference between Focus and Select.
Select the Textbox you want to assign a focus to in the Design View Window.
Under the Properties window, set the TabIndex to 0 (zero).
I didn't even have to use the TextBox1.Focus() command. It still bothers me that the TabIndex overrides the Focus command.
What I tried (and worked for me), was to set the Focus() of the Textbox in the event handler Shown() [VB]:
Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown
Me.Textbox1.Focus()
End Sub
Note: the Select() method just didn't do the job. I hope this helps anyone else that comes with this same issue.

Why BackgroundWorker infinite loop stops?

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
BackgroundWorker1.RunWorkerAsync()
End Sub
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
MsgBox("test")
End Sub
Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
BackgroundWorker1.RunWorkerAsync()
End Sub
Once I click the Button1 ,Messagebox appears.When click okay with "Return" (enter) key it appears again and again...But when I click Return key permanently,almost 5 seconds later programs gives me the run time error.
Error is not English in my computer and I translated it.It is nearly mean "BackgroundWorker is busy,can't do two procces in the same time..."
I know that error.It is because of trying to run BackgroundWorker while it is running.In the code it just start with RunWorkerCompleted event.So it can't start again if "Work is not Completed".Who runs the BackgroundWorker ?
You need to read this post first, it talks about the dangers of re-entrancy and how dialogs (like MsgBox) solve the problem.
Which is what it is not doing in your program. A dialog can only be modal against other windows that are created on the same thread. That worker thread doesn't have any. So there is nothing that stops your Enter key press from also being seen by the control that has the focus. Button1. Note how you can simply use the mouse to select your main window and click the button. Kaboom.
That doesn't go wrong often enough as-is, you can help by leaning on the Enter key so it starts repeating. It will usually be detected by the message box window. But not always, there's a split second between DoWork ending and it starting back up. Just enough to give the UI thread a chance to see the keystroke. Now that Enter keypress operates Button1 and it starts the BGW back up again. So does the RunWorkerCompleted event handler, it cannot be started twice. Kaboom.
That's not the only problem with that dialog, you haven't discovered the other failure mode yet. A dialog needs an owner window, one that it can be displayed on top of. That message box does have one, it has to fallback to the desktop window. Now it is crapshoot which window is going to be in front. Could be the dialog, could be your main window. With the message box underneath your main window. The user cannot see it, has no idea that there is one. No taskbar button either.
Long story short: this cannot work. Only display UI on the UI thread. Only use a worker thread to do non-UI related work.

Windows button appearance in a VB 2008 application

I am creating a Win32-application in Visual Basic 2008. I would like to have a button in the form, with custom color (BackColor), on MouseEnter event. This works fine, but as you can see below, this custom color doesn't cover the whole area of the button. The button border remains as standard (Windows 7). Can I somehow have this color for the whole button? I don't want to use Flat button style, I prefer this Standard style, which has the normal Windows look.
What I typically do is this I first gather two buttons that look similar, such as this Pic A and B.
Then I will put in those two picture into my Resources.
After I begin coding the function such as the Example I have made down below.
Now their are two ways of going about this. There is a hover option as seen below:
Private Sub PictureBox1_MouseHover(sender As Object, e As EventArgs) Handles PictureBox1.MouseHover
PictureBox1.Image = My.Resources.Button1
End Sub
or there is this option which has way better response times when moving your mouse:
Private Sub PictureBox1_MouseEnter(sender As Object, e As EventArgs) Handles PictureBox1.MouseEnter
PictureBox1.Image = My.Resources.Button1
End Sub
Then you need this to set things back to normal:
Private Sub PictureBox1_MouseLeave(sender As Object, e As EventArgs) Handles PictureBox1.MouseLeave
PictureBox1.Image = My.Resources.Button
End Sub
Real simple code but in a realistics thats all you need! I typically hate the buttons! I find myself messing with the button look more then I actually code, really simple to just go to Photoshop and make a easy button that looks good!
I read your Question don't worry but to be honest that style button looks old fashion the buttons I made are more up to date and Modern!