Results 1 to 7 of 7

Thread: Is it possible for a 3rd party to hold on to a variable reference in vb.net?

  1. #1
    Lively Member
    Join Date
    Feb 08
    Posts
    75

    Is it possible for a 3rd party to hold on to a variable reference in vb.net?

    For example when i pass a variable to a function byref i can use it to directly modify the other class's variable but only while in scope of that function, i want to store that reference to do just that but later. In c++ i would just pass the variable pointer and store that in a variable for later use but how would you do that in vb?

  2. #2
    Burning Member Niya's Avatar
    Join Date
    Nov 11
    Posts
    3,094

    Re: Is it possible for a 3rd party to hold on to a variable reference in vb.net?

    All class variables are references, even when you pass them by value:-
    vbnet Code:
    1. '
    2. Public Class Form1
    3.  
    4.     Private ca As New ClassA
    5.  
    6.     Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    7.         ChangeValue(10, ca)
    8.         MsgBox(ca.Value)
    9.     End Sub
    10.  
    11.     Private Sub ChangeValue(ByVal value As Integer, ByVal clsA As ClassA)
    12.         clsA.Value = value
    13.     End Sub
    14. End Class
    15.  
    16. Public Class ClassA
    17.     Private _value As Integer = 0
    18.  
    19.     Public Property Value() As Integer
    20.         Get
    21.             Return _value
    22.         End Get
    23.         Set(ByVal value As Integer)
    24.             _value = value
    25.         End Set
    26.     End Property
    27.  
    28.  
    29. End Class

    Although ca is passed by value to ChangeValue, the message box would display the value set inside the sub because all that is passed is a reference to that class. Classes create reference types.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | Create Sortable BindingList(not mine) | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading


    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. -jmcilhinney

  3. #3
    Lively Member
    Join Date
    Feb 08
    Posts
    75

    Re: Is it possible for a 3rd party to hold on to a variable reference in vb.net?

    thanks but that totally doesn't help me at all. heres what im trying to do

    Code:
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Dim t As New Threading.Thread(Sub() Tweener(Button1.Width, 100, 400))
            t.Start()
        End Sub
    
    
        Public Sub Tweener(ByRef target As Object, ByVal Amount As Integer, ByVal tPeriod As Integer)
            Dim stopat As Integer = Environment.TickCount + tPeriod
            Dim tFrame = 40
            Dim chunk As Integer = Amount / (tPeriod / tFrame)
            While Environment.TickCount < stopat
                target += chunk
                Application.DoEvents()
                Threading.Thread.Sleep(tFrame)
            End While
        End Sub
    The idea is that i could throw whatever variable, amount and time period to the tweener and it would deal with the animation instead of me having to explicitly set it up for said variable. Alas the code doesn't work since vb doesn't allow cross thread form manipulation.

  4. #4
    Burning Member Niya's Avatar
    Join Date
    Nov 11
    Posts
    3,094

    Re: Is it possible for a 3rd party to hold on to a variable reference in vb.net?

    Your problem has nothing to do with references or pointers or any of that. You simply cannot alter UI elements from any thread other than the UI thread. Attached below is an example of how to properly alter UI elements from another thread. You can read from this post to understand why you can't alter controls directly from foreign threads.
    Attached Files Attached Files
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | Create Sortable BindingList(not mine) | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading


    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. -jmcilhinney

  5. #5
    Lively Member
    Join Date
    Feb 08
    Posts
    75

    Re: Is it possible for a 3rd party to hold on to a variable reference in vb.net?

    i dont want to alter it from another thread, what i want is to delegate the management to an universal construct of some kind. If i could store the reference of a variable i could do it via a time for example from within the same thread, it doesn't matter which way i get to it as long as i do.

  6. #6
    Frenzied Member Evil_Giraffe's Avatar
    Join Date
    Aug 02
    Location
    Suffolk, UK
    Posts
    1,876

    Re: Is it possible for a 3rd party to hold on to a variable reference in vb.net?

    You cannot pass a reference to the Width property, as you'd need to pass the backing field value ByRef rather than the property, and you don't have access to that. What you could do is pass the button itself, although then you'd be tied to altering the Width property on anything you passed. What I might be tempted to do is instead pass a Func and an Action. Assuming that you solve the cross threading issue separately (i.e. so I'm not completely rewriting your sample) you could look at something like this:

    Code:
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim t As New Threading.Thread(Sub() Tweener(Function() (Button1.Width), Function(newWidth As Integer) (Button1.Width = newWidth), 100, 400))
        t.Start()
    End Sub
    
    Public Sub Tweener(ByVal getTarget As Func(Of Integer), ByVal setTarget As Action(Of Integer), ByVal Amount As Integer, ByVal tPeriod As Integer)
        Dim stopat As Integer = Environment.TickCount + tPeriod
        Dim tFrame = 40
        Dim chunk As Integer = Amount / (tPeriod / tFrame)
        While Environment.TickCount < stopat
            setTarget(getTarget() + chunk)
            Application.DoEvents()
            Threading.Thread.Sleep(tFrame)
        End While
    End Sub

  7. #7
    Frenzied Member Evil_Giraffe's Avatar
    Join Date
    Aug 02
    Location
    Suffolk, UK
    Posts
    1,876

    Re: Is it possible for a 3rd party to hold on to a variable reference in vb.net?

    Another option is to model the concept of an animatable value with its own type:

    vbnet Code:
    1. Public Interface IAnimatable(Of T)
    2.     Property AnimationValue As T
    3. End Interface

    Which you can provide a concrete implementation for animating the width of a control - which can as part of its implementation deal with the issues of cross threading:
    vbnet Code:
    1. Public Class ControlWidthAnimator
    2.     Implements IAnimatable(Of Integer)
    3.  
    4.     Private _control As Control
    5.     Private _width As Integer
    6.  
    7.     Public Sub New(control As Control)
    8.         _control = control
    9.         _width = _control.Width
    10.     End Sub
    11.  
    12.     Public Property AnimationValue As Integer Implements IAnimatable(Of Integer).AnimationValue
    13.         Get
    14.             Return _width
    15.         End Get
    16.         Set(value As Integer)
    17.             _width = value
    18.             SetWidth(_width)
    19.         End Set
    20.     End Property
    21.  
    22.     Private Sub SetWidth(newWidth As Integer)
    23.         If (_control.InvokeRequired) Then
    24.             _control.Invoke(New Action(Of Integer)(AddressOf SetWidth), newWidth)
    25.         Else
    26.             _control.Width = newWidth
    27.         End If
    28.     End Sub
    29. End Class

    Allowing your Tweener code to deal with the abstract concept of an animatable value:
    vbnet Code:
    1. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    2.     Dim t As New Threading.Thread(Sub() Tweener(New ControlWidthAnimator(Button1), 100, 400))
    3.     t.Start()
    4. End Sub
    5.  
    6. Public Sub Tweener(ByVal animatable As IAnimatable(Of Integer), ByVal Amount As Integer, ByVal tPeriod As Integer)
    7.     Dim stopat As Integer = Environment.TickCount + tPeriod
    8.     Dim tFrame = 40
    9.     Dim chunk As Integer = Amount / (tPeriod / tFrame)
    10.     While Environment.TickCount < stopat
    11.         animatable.AnimationValue += chunk
    12.         Application.DoEvents()
    13.         Threading.Thread.Sleep(tFrame)
    14.     End While
    15. End Sub

    (I'd still deal with the animation with some kind of timer (be that a Windows.Forms.Timer on the UI thread or a System.Threading.Timer that returns on a worker thread) rather than sleeping in a worker thread, but now that's an orthogonal aspect of the code that can be altered independently of how the control itself gets altered.)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •