Results 1 to 2 of 2

Thread: [RESOLVED] Invoking many controls

  1. #1

    Thread Starter
    Frenzied Member
    Join Date
    Dec 2001
    Posts
    1,331

    Resolved [RESOLVED] Invoking many controls

    Hello,

    The function below will be called from another thread. So the control themselves will have to be invoked so that the correct thread that created them can change the properties.

    However, as I have many controls that need to be updated. I don't really want to write all those delegates for each one. I have done one below. However, I am thinking that is a lot of code. Is there anyway to shorten this?

    Many thanks,

    Code:
    Public Sub SetIdleState(ByVal callStatusMsg As String)
    			Me.btnCallAnswer.Text = CATWinSIP_MsgStrings.Call
    			Me.btnEndCallReject.Text = CATWinSIP_MsgStrings.EndCall
    			Me.btnHoldUnhold.Text = CATWinSIP_MsgStrings.Hold
    
    			Me.btnCallAnswer.Enabled = True
    			Me.btnRedial.Enabled = True
    			Me.btnEndCallReject.Enabled = False
    			Me.btnHoldUnhold.Enabled = False
    
    			If Me.statusDisplay1.InvokeRequired Then
    				statusDisplay1.Invoke(New UpdateCallStatusDelegate(AddressOf Me.UpdateCallStatus), callStatusMsg)
    			Else
    			   Me.statusDisplay1.CallStatus = callStatusMsg
    			End If
    End Sub
    
    		' Delegate for marshalling the call on the correct thread.
    		Private Delegate Sub UpdateCallStatusDelegate(ByVal callStatusMsg As String)
    		Private Sub UpdateCallStatus(ByVal callStatusMsg As String)
    			Me.statusDisplay1.CallStatus = callStatusMsg
    		End Sub
    steve

  2. #2
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,344

    Re: Invoking many controls

    I don't understand your code. The fact that you're testing InvokeRequired in your SetIdleState method implies that that method is called on a secondary thread, yet you're accessing multiple controls in that method. Have you read the Controls & Multi-threading thread of mine in the CodeBank? It outlines a number of steps you can perform and those steps NEVER change. The fact that you have multiple controls to access is irrelevant. The steps are:

    1. Write a method that does what you need:
    vb.net Code:
    1. Public Sub SetIdleState(ByVal callStatusMsg As String)
    2.     Me.btnCallAnswer.Text = CATWinSIP_MsgStrings.Call
    3.     Me.btnEndCallReject.Text = CATWinSIP_MsgStrings.EndCall
    4.     Me.btnHoldUnhold.Text = CATWinSIP_MsgStrings.Hold
    5.  
    6.     Me.btnCallAnswer.Enabled = True
    7.     Me.btnRedial.Enabled = True
    8.     Me.btnEndCallReject.Enabled = False
    9.     Me.btnHoldUnhold.Enabled = False
    10.  
    11.     Me.statusDisplay1.CallStatus = callStatusMsg
    12. End Sub
    2. Test the InvokeRequired property of a control, moving the current contents of the method into the Else block:
    vb.net Code:
    1. Public Sub SetIdleState(ByVal callStatusMsg As String)
    2.     If Me.InvokeRequired Then
    3.  
    4.     Else
    5.         Me.btnCallAnswer.Text = CATWinSIP_MsgStrings.Call
    6.         Me.btnEndCallReject.Text = CATWinSIP_MsgStrings.EndCall
    7.         Me.btnHoldUnhold.Text = CATWinSIP_MsgStrings.Hold
    8.  
    9.         Me.btnCallAnswer.Enabled = True
    10.         Me.btnRedial.Enabled = True
    11.         Me.btnEndCallReject.Enabled = False
    12.         Me.btnHoldUnhold.Enabled = False
    13.  
    14.         Me.statusDisplay1.CallStatus = callStatusMsg
    15.     End If
    16. End Sub
    3. Create a delegate by copying the method declaration, changing the name and adding the Delegate key word:
    vb.net Code:
    1. Public Delegate Sub SetIdleStateInvoker(ByVal callStatusMsg As String)
    2.  
    3. Public Sub SetIdleState(ByVal callStatusMsg As String)
    4.     If Me.InvokeRequired Then
    5.  
    6.     Else
    7.         Me.btnCallAnswer.Text = CATWinSIP_MsgStrings.Call
    8.         Me.btnEndCallReject.Text = CATWinSIP_MsgStrings.EndCall
    9.         Me.btnHoldUnhold.Text = CATWinSIP_MsgStrings.Hold
    10.  
    11.         Me.btnCallAnswer.Enabled = True
    12.         Me.btnRedial.Enabled = True
    13.         Me.btnEndCallReject.Enabled = False
    14.         Me.btnHoldUnhold.Enabled = False
    15.  
    16.         Me.statusDisplay1.CallStatus = callStatusMsg
    17.     End If
    18. End Sub
    In the If block, invoke the current method using an instance of the delegate you just declared:
    vb.net Code:
    1. Public Delegate Sub SetIdleStateInvoker(ByVal callStatusMsg As String)
    2.  
    3. Public Sub SetIdleState(ByVal callStatusMsg As String)
    4.     If Me.InvokeRequired Then
    5.         Me.Invoke(New SetIdleStateInvoker(AddressOf SetIdleState), _
    6.                   callStatusMsg)
    7.     Else
    8.         Me.btnCallAnswer.Text = CATWinSIP_MsgStrings.Call
    9.         Me.btnEndCallReject.Text = CATWinSIP_MsgStrings.EndCall
    10.         Me.btnHoldUnhold.Text = CATWinSIP_MsgStrings.Hold
    11.  
    12.         Me.btnCallAnswer.Enabled = True
    13.         Me.btnRedial.Enabled = True
    14.         Me.btnEndCallReject.Enabled = False
    15.         Me.btnHoldUnhold.Enabled = False
    16.  
    17.         Me.statusDisplay1.CallStatus = callStatusMsg
    18.     End If
    19. End Sub

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