-
Nov 27th, 2013, 02:17 PM
#1
Thread Starter
Addicted Member
[RESOLVED] Struggling with trying to access a control on a form from seperate classes...
I still cant seem to wrap my head around this concept.
I get the classes and forms are completely separate objects that can't see each other initially unless you pass on the data from the form to the class or vice versa. What I can't figure out is how to correctly pass those parameters without multiple errors occurring. And yes jmc, i did check out your multiple forms code in your signature : P .
I have 6 checkboxes inside a tab container located on "tabpage2" on the main form "QoE" and I have multiple classes that need to know the check states of those checkboxes.
I first went about this using:
in each class, then calling the checkboxes like this:
Code:
If f.chkTcpRTT.checked Then...
but the result is always coming back "False" whether the box is checked or not, which I am assuming has to do with the fact that I am using the word "New". it looks like its just creating a new instance of the form and not actually giving me any information about the form as it is currently. With that being said:
Code:
Dim f as QoE or Dim f = QoE
Doesnt work.
My second thought was to use the property method, so I use this on the QoE form:
Code:
Public Shared Property getchecker(ByVal chk As CheckBox) As Boolean
Get
Return chk.Checked
End Get
Set(ByVal value As Boolean)
chk.Checked = value
End Set
End Property
and then I could call it using:
Code:
QoE.getchecker(ChkTcpRTT)
But this still leaves me with having to pass an object from the other class which I cant figure out. so I tried this:
Code:
Public Shared Property getchecker(ByVal txt As string) As Boolean
Get
For Each ctrl as Control in TabPage2.Controls
If ctrl.name = txt Then
Return ctrl.Checked
End If
Next
End Get
Set(ByVal value As Boolean)
txt.Checked = value
End Set
End Property
And then I could call it using:
Code:
QoE.getChecker("ChkTcpRTT")
But then I get the error: "Cannot refer to an instance member of a class from within a shared method or shared member initializer without an explicit instance of the class." on the "TabPage2.Controls"
The last thing I've tried was different variations of Event Raiser to see if I could access the control from within the form and send it back to the class. But I either get the error above or I am unable to get the check state without actually having to set a global variable (which I know cant be good practice)
Any help with an explanation will be more than greatly appreciated.
Thanks Guys
-
Nov 27th, 2013, 02:41 PM
#2
Re: Struggling with trying to access a control on a form from seperate classes...
You are right with the point about New creating a new form. A form is just a class. You create an instance of a form just like you create an instance of the classes you are using. So, the instance of the form that is being shown is the instance that you need access to in your classes.
The use of the Shared property was an interesting approach. That does run into a problem, as you have noted. A Shared method has to exist before ANY instance of the form exists. You can see this for yourself by creating a class with a single Shared method. You would find that you can call that method with ClassName.MethodName without ever creating an instance of the class. Therefore, the Shared method can't refer to any particular instance of the class because the method can be called when NO instance of the class exists.
There are two ways to solve this. One is to rely on the default instance of the form. I would only suggest this because you mentioned that the form in question is the main form. Default instances generally cause more headaches than they solve and I don't like them, but for the main form....well, there are times when that is just the best way. The default instance is the instance with the same name as the form itself. So, if your form is called QoE, then you might be able to simply call QoE.SomeControl, because the compiler will (probably) quietly create a variable like this:
Public QoE As QoE
and set it to the form you are showing. Mostly, this creates trouble, and if you added a constructor to the form that takes arguments, the default instance won't exist anyways.
This does present an alternative, though, because you could make a global variable by declaring a public instance in a module:
Public myQoE As QoE
then in the load event (or the constructor) of the form you could set that to the current instance:
myQoE = Me
and now the instance is available to EVERYTHING in the project. It's largely because it is available to EVERYTHING that people don't like global variables. Life gets messy pretty fast if those aren't used with great care. This approach, along with the default instance, both violate the principles of Object Oriented design, though, because your other classes would have access to things that they don't know about. If you use either of those methods, the classes become tied to the existence of either the default instance or the global variable and if either goes away, the class fails.
The other alternative is that all of your classes have a constructor that takes a QoE instance as an argument. When you create the class, you pass the current form instance to the class, which then stores it in a member variable and accesses it through that member variable. This is in keeping with OO design, since the class is only using an object that was passed to it.
My usual boring signature: Nothing
-
Nov 27th, 2013, 02:56 PM
#3
Thread Starter
Addicted Member
Re: Struggling with trying to access a control on a form from seperate classes...
When you create a class how would you pass the current form instance to the class?
-
Nov 27th, 2013, 03:30 PM
#4
Re: Struggling with trying to access a control on a form from seperate classes...
here's an example of passing a form (or control) to a class:
Code:
Public Class Class1
Dim callingForm As Form1
Private WithEvents tmr As New Timer
Dim colors() As Color = {Color.Red, SystemColors.Control}
Dim colorIndex As Integer = 0
Public Sub New(ByVal caller As Form1)
callingForm = caller
tmr.Interval = 250
End Sub
Public Sub flashForm()
callingForm.Text = "see???"
tmr.Start()
AddHandler callingForm.Paint, AddressOf paintForm
End Sub
Private Sub tmr_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles tmr.Tick
colorIndex += 1
callingForm.Invalidate()
End Sub
Private Sub paintForm(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs)
ControlPaint.DrawBorder(e.Graphics, callingForm.ClientRectangle, colors(colorIndex Mod 2), ButtonBorderStyle.Solid)
End Sub
End Class
this is the form:
Code:
Public Class Form1
Dim c As Class1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
c = New Class1(Me)
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
c.flashForm()
End Sub
End Class
- Coding Examples:
- Features:
- Online Games:
- Compiled Games:
-
Nov 27th, 2013, 03:48 PM
#5
Thread Starter
Addicted Member
Re: Struggling with trying to access a control on a form from seperate classes...
Haha i feel like you made that waay harder then it needed to be : P
Just in case someone comes across this, I want to condense the code above just to make it a little more readable/understandable for n00bs such as myself : P
But the code is perfect, thank you both, especially Shaggy for explaining to me in 5 minutes what I couldn't figure out with 2 days of google searching. This should really be in MSDN
A Shared method has to exist before ANY instance of the form exists. You can see this for yourself by creating a class with a single Shared method. You would find that you can call that method with ClassName.MethodName without ever creating an instance of the class. Therefore, the Shared method can't refer to any particular instance of the class because the method can be called when NO instance of the class exists.
Code:
Public Class Form1
Dim c As Class1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
c = New Class1(Me)
End Sub
End Class
Code:
Public Class Class1
Dim callingForm As Form1
Public Sub New(ByVal caller As Form1)
callingForm = caller
End Sub
end class
and then any control and object in form1 can be called from class1 by using callingForm .... such as :
Code:
callingForm.Textbox1.Text = "blah"
-
Nov 27th, 2013, 04:17 PM
#6
Re: [RESOLVED] Struggling with trying to access a control on a form from seperate cla
Note that if ALL you needed was one of the controls on the form, it would probably be better to have the class just take that one control.
Also, since you have passed the form to the class (or a control, if you chose that), then you can handle events from the form or the controls on the form inside the class. I'm not suggesting that you do that, but it is possible. You'd have to have some AddHandler statements within the class to hook things up.
My usual boring signature: Nothing
-
Nov 27th, 2013, 05:13 PM
#7
Re: Struggling with trying to access a control on a form from seperate classes...
- Coding Examples:
- Features:
- Online Games:
- Compiled Games:
Tags for this Thread
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
|