Results 1 to 7 of 7

Thread: [RESOLVED] Struggling with trying to access a control on a form from seperate classes...

  1. #1

    Thread Starter
    Addicted Member
    Join Date
    Sep 2011
    Location
    Seattle
    Posts
    218

    Resolved [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:

    Code:
    dim f as new QoE
    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

  2. #2
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    38,989

    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

  3. #3

    Thread Starter
    Addicted Member
    Join Date
    Sep 2011
    Location
    Seattle
    Posts
    218

    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?

  4. #4
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    25,464

    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

  5. #5

    Thread Starter
    Addicted Member
    Join Date
    Sep 2011
    Location
    Seattle
    Posts
    218

    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"

  6. #6
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    38,989

    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

  7. #7
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    25,464

    Re: Struggling with trying to access a control on a form from seperate classes...

    Quote Originally Posted by Zmcpherson View Post
    Haha i feel like you made that waay harder then it needed to be : P
    I was just trying to make the example useful as well as informative, + show you some of the possibilities with classes...

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
  •  



Click Here to Expand Forum to Full Width