|
-
Jul 30th, 2012, 07:36 PM
#1
Thread Starter
Hyperactive Member
[RESOLVED] Forms Colliding
i always have this issue, when my program is loading or processing a function with complex queries. my forms collides with forms from other apps, and the interface becomes irresponsive. this doesn't look professional, is there a way to get around this
Thanks
-
Jul 30th, 2012, 09:23 PM
#2
Re: Forms Colliding
I assume what you mean is that your form doesn't get repainted when other forms are dragged over it. That's because you are performing long-running tasks on the UI thread so it is too busy to repaint the UI. You need to perform such tasks on a secondary thread so that the UI thread is free to repaint the UI and respond to user input. There are various ways that this can be accomplished but, for simple scenarios in a WinForms app, one of the most common is to use a BackgroundWorker. For examples, you can follow the CodeBank link in my signature and check out my thread on Using The BackgroundWorker. If you need more help then please provide specific details of what you're trying to achieve.
-
Aug 8th, 2012, 12:30 AM
#3
Thread Starter
Hyperactive Member
Re: Forms Colliding
Great Thanks.. just one problem sometimes when processing larger amount of data, program hangs, right after displaying the complete message, after the BackgroundWorker1.RunWorkerCompleted event and i end up crashing and reruning the process
Code:
Private Sub mainform_Shown(sender As Object, e As System.EventArgs) Handles Me.Shown
Call initialise()
End Sub
Sub initialise()
BackgroundWorker1.RunWorkerAsync()
End Sub
Private Sub BackgroundWorker1_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
' This method executes after the form is loaded
PnlDTL.Visible = False
PnlHdr.Visible = False
SqlUpdates()
updatePrTables()
ApprovePRHDR()
lblinfo.Visible = 0
pbar.Visible = 0
PnlDTL.Visible = 1
PnlHdr.Visible = 1
' Now populate the GrdHDR
PopulateGrdHDR()
MsgBox("grdHdr populated")
End Sub
Private Sub BackgroundWorker1_RunWorkerCompleted(sender As System.Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
MsgBox("completed")
End Sub
any ideas ??
Last edited by wiss.dev; Aug 8th, 2012 at 12:36 AM.
-
Aug 8th, 2012, 12:57 AM
#4
Re: Forms Colliding
First things first, why are you assigning Integers to Boolean properties? The Visible property of a control is type Boolean. You obviously know that or you would not be using False in the first two lines, so why are you using 0 and 1 later on?
As for the issue, it's hard to say what the issue is but, if you've read my CodeBank thread, you should know that you DO NOT touch the UI in the DoWork event handler, or any method called from the DoWork event handler for that matter. Panels, Labels and ProgressBars are all controls and are therefore part of the UI. Background work only is what you do in the background thread and updating the UI is the exact opposite of background work.
-
Aug 8th, 2012, 05:44 PM
#5
Thread Starter
Hyperactive Member
Re: Forms Colliding
because i always thought that 0 and 1 are short cuts for true and false and never had issues with that.
as for the backgroundWorker, i will test updating the progressBar using the b/worker progress method and see how it goes
Last edited by wiss.dev; Aug 8th, 2012 at 08:05 PM.
-
Aug 8th, 2012, 09:49 PM
#6
Re: Forms Colliding
All VB.NET developers should always have Option Strict On for all projects and only turn it Off in specific files where and when it's needed, which is very rarely. Unfortunately it is Off by default to make life easier for beginners, but that actually causes just about as many issues as it solves. With Option Strict On, using Integers where Booleans are expected will cause a compilation error. Besides anything else, you should always try to be consistent. The fact that you're using Booleans and Integers for the same purpose within a couple of lines of each other is obviously inconsistent. Things like that tend to make people reading it wonder whether they are different for a specific reason or not.
-
Aug 9th, 2012, 12:17 AM
#7
Thread Starter
Hyperactive Member
Re: Forms Colliding
Thanks for the info , will keep it in mind. the issue was that i was calling subs/functions in sequence with BackgroundWorker1.Dowork which got evaluated at the same time . so i had to call the other subs from the runWorkerComplted method to ensure they evaluate after the process is complete...
-
Aug 12th, 2012, 07:11 PM
#8
Thread Starter
Hyperactive Member
Re: Forms Colliding
one more thing, i call a public shared sub in a another class in the dowork event, but its not updating the progress bar,, any ideas ?
here is an example :
Code:
Private Sub BackgroundWorker1_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Class1.run()
End Sub
Private Sub BackgroundWorker1_ProgressChanged(sender As System.Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
pBar.Value = e.ProgressPercentage
End Sub
Class1:
Code:
Public Class Class1
Public Shared Sub run()
For i As Integer = 0 To 10
Threading.Thread.Sleep(500)
Form1.BackgroundWorker1.ReportProgress(i * 10, "")
Next
End Sub
End Class
-
Aug 12th, 2012, 07:19 PM
#9
Re: Forms Colliding
Follow the Blog link in my signature and check out my post on Default Instances.
-
Aug 12th, 2012, 08:42 PM
#10
Thread Starter
Hyperactive Member
Re: Forms Colliding
i read your blog and did some research.. i cant really see what i have missed
in your example you did this :
Form2.TextBox1.Text = Me.TextBox1.Text
in my class 2 i have :
Form1.BackgroundWorker1.ReportProgress(i * 10, "") or Form1.pBar.Value = i * 10
what else i need to do beside qualifying with the class name, the only workaround i can think of is to set a timer to call report progress event with a public shared integer variable which is updated in class1.Run sub !!
Last edited by wiss.dev; Aug 12th, 2012 at 08:45 PM.
-
Aug 12th, 2012, 09:05 PM
#11
Re: Forms Colliding
I specifically state in my Blog post:
When can’t you use default instances?
3. You need to access a form from a secondary thread.
The whole point of the DoWork event handler is that it's executed on a secondary thread. If the DoWork event handler is executed on a secondary thread then every method you call from it, e.g. Class1.run, is executed on that same secondary thread, which is the whole point. By using the default instance there you are using the default instance specific to that thread, which is a completely different object to the one that was created and displayed on the UI thread in the first place. Your code is working perfectly, i.e. it is updating the ProgressBar on the default Form1 instance for the current thread. The problem is that that is not the Form1 instance whose ProgressBar you want to update because that is not the Form1 instance that you displayed to the user. This is a perfect example of why many people, myself included, think that we would be better off without default form instances.
-
Aug 13th, 2012, 12:44 AM
#12
Thread Starter
Hyperactive Member
Re: Forms Colliding
 Originally Posted by jmcilhinney
think that we would be better off without default form instances.
is that something in the form properties, or project properties that i can switch off ??
-
Aug 13th, 2012, 12:49 AM
#13
Re: Forms Colliding
No, but nor would you need to. If you don't want to use them just don't use them. It's easy to know when you are:
1. The IDE turns the names of types a different colour so if your form reference is not black text in the code window then it's a default instance.
2. To create pretty much any object explicitly you need to invoke a constructor using the New keyword. If you didn't use New to create your form instance then it's a default instance.
-
Aug 13th, 2012, 06:39 PM
#14
Thread Starter
Hyperactive Member
Re: Forms Colliding
Thanks for the details, but that is exactly what i'm doing
Dim frmB2B As New B2B
frmB2B.ShowDialog(Me)
i have another, class where i put all the common function and subs
from what you have explained, i understood that the doWork updates default instance. so in my case there is no default instance. and UI gets updated when invoking the .ProgressChanged event if the caller is in frmB2B, but it doesnt seem to update if the caller is in the commons class.
here is an illustration of what i have
Code:
class B2B
bgWorker.DoWork
call AB()
Call Commons.XY()
end sub
sub AB
bgWorker.progesschange(...) ' Updates UI
end Sub
end class
class commons
sub XY
b2b.bgWorker.progesschange(...) ' UI not updated
end sub
end class
as i mentioned before, if i set a timer in B2B to update the progress Bar from a public variable updated in XY, this worked for me
-
Aug 13th, 2012, 06:46 PM
#15
Re: Forms Colliding
In the highlighted code you are creating an instance explicitly and displaying it. When you later try to update the progress, you do NOT refer to that instance that you created and displayed. You refer to the default instance. That is the problem. You display one form and then update another. Look at your example code:
Code:
class B2B
bgWorker.DoWork
call AB()
Call XY()
end sub
sub AB
bgWorker.progesschange(...) ' Updates UI
end Sub
end class
class commons
sub XY
b2b.bgWorker.progesschange(...) ' UI not updated
end sub
end class
What is it that I have highlighted? Is it a variable that refers to an instance that you created yourself? No, it is the default instance.
-
Aug 13th, 2012, 07:45 PM
#16
Thread Starter
Hyperactive Member
Re: Forms Colliding
That was my first thought, but i have frmB2b defined in the startup main form, are you saying that id need to change the scope when defining frmB2b ? how can i refer to the new instance (frmB2b) from the commons class
-
Aug 13th, 2012, 08:10 PM
#17
Re: Forms Colliding
So you have declared a variable 'frmB2b' somewhere in your main form, create a form object and assigned that object to the variable. So what? Why does that mean that you magically have access to that variable or that object in some other class?
If I make a cake in my kitchen, does everyone else magically have access to that cake in their kitchen? If they make a cake themselves in their kitchen and put icing on it, does that mean that the cake in my kitchen magically has icing on it? Of course not. If I make a cake in my kitchen and I want someone else to be able to have a piece of that cake then I have to take that cake around to their house. That's how objects work, isn't it?
That's exactly how objects work in programming too. If you create an instance of B2B in your main form and assign it to a variable in that main form then the only way to access that object is via that variable. Your 'commons' class doesn't magically have access to it. It doesn't even know it exists. For your 'commons' class to be able to access that object, your main form must pass a reference to the object to the 'commons' class. If you want to be able to access an object then you need to be able to see a reference to that object. It's that simple. This may seem a difficult thing to do but it's not. It all comes down to design. Poor design makes things like this clunky, although definitely not impossible. Good design makes them smooth and easy.
This is exactly why I, and others, don't like default instances: they give the impression that forms don't work the same way as other objects. They do though, even when using default instances. The default instance is simply like a property of a module or a Shared property of a class.
-
Aug 13th, 2012, 08:26 PM
#18
Thread Starter
Hyperactive Member
Re: Forms Colliding
Thanks again, i do understand scoping, and you are right, it might be a bad design because i don't know another way of doing it. would be great if you have an example of
your main form must pass a reference to the object to the 'commons' class
-
Aug 13th, 2012, 08:48 PM
#19
Re: Forms Colliding
Like so many people, you are assuming that this is difficult and therefore trying to make it difficult. You don't need an example of that. It's as simple as it gets: declare a variable and assign a value.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|