Search code examples
vb.netwinformsdelegatespanelgif

Animated gif in picturebox visibility change with delegate subs and background thread


I have a Telerik RadRibbonBar in the main form, in which there are many buttons. Some of these buttons make some panels in the form visible which fills all the main form except for the RadRibbonBar and its buttons.

These panels have some forms which are dynamically calculated and they take between 0 seconds to 2-3 minutess to open. Thus we decided to put a form in between with a panel and a PictureBox with an animated gif. My problem is that I cannot get the animated gif from the picture box to show once I set the new form with the animated gif to .visible = False.

I put some code here to see if someone can help me.

Public Sub MICommand1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MICommand1.Click
    cargando = True
    makevisiblePanel(1)
    azkenpanelzenbakia = 1
    cargando = False
End Sub
Public Sub MICommand2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MICommand2.Click
    cargando = True
    makevisiblePanel(2)
    azkenpanelzenbakia = 2
    cargando = False
End Sub

And so on with many other buttons. Now the makevisiblePanel(byval panel as integer)

Private Sub makevisiblePanel(ByVal panel As Integer)
    rf.Visible = True
    If Not loaded Then
        makeeverypanelInvisible()
        firstCallPanelInLoad(panel)
        rf.Visible = False
    Else
        makeeverypanelInvisible()
        backgroundworkerRA(panel)
    End If
End Sub

The background worker is defined like this:

Private Sub backgroundworkerRA(ByVal panel As Integer)
    Dim t As New Threading.Thread(Sub() selectVisiblePanel(zein))
    t.IsBackground = True
    t.Start()
End Sub
Private Sub selectVisiblePanel(ByVal zein As Integer)
    selectVisiblePanel_threadasko_rf()
    Select Case zein
        Case 0
            selectVisiblePanel_threadasko_P10()
            selectVisiblePanel_threadasko_Rp()
        Case 1
            selectVisiblePanel_threadasko_P1()
            selectVisiblePanel_threadasko_Rd1()
        'Some lot more cases
    End Select
    selectVisiblePanel_threadasko_rf_v(False)
    Select Case zein
        Case 0
            selectVisiblePanel_threadasko_P10Front()
        Case 1
            selectVisiblePanel_threadasko_P1Front()
        'Lots more cases
    End Select
End Sub

I put first the panels visible and then put them in the back of the form with send.toBack and then after making my panel not visible I put them back in front.

Like this with each selectVisiblePanel which has a Delegate Sub and a Panel#number.Visible = True. Like this:

Delegate Sub rfCallBack()
Private Sub selectVisiblePanel_threadasko_rf()
    If Me.rf.InvokeRequired Then
        Dim d As New rfCallBack(AddressOf selectVisiblePanel_threadasko_rf)
        Me.Invoke(d, New Object() {})
    Else
        Me.rf.WindowState = FormWindowState.Maximized
    End If
End Sub
Delegate Sub rf_vCallBack(ByVal vf As Boolean)
Private Sub selectVisiblePanel_threadasko_rf_v(ByVal vf As Boolean)
    If Me.rf.InvokeRequired Then
        Dim d As New rf_vCallBack(AddressOf selectVisiblePanel_threadasko_rf_v)
        Me.Invoke(d, New Object() {vf})
    Else
        Me.rf.Visible = vf
    End If
End Sub
Delegate Sub P1CallBack()
Private Sub selectVisiblePanel_threadasko_P1()
    If Me.Panel1.InvokeRequired Then
        Dim d As New P1CallBack(AddressOf selectVisiblePanel_threadasko_P1)
        Me.Invoke(d, New Object() {})
    Else
        Me.Panel1.Visible = True
        Me.Panel1.SendToBack()
    End If
End Sub
Delegate Sub RD1CallBack()
Private Sub selectVisiblePanel_threadasko_Rd1()
    If Me.RadDock1.InvokeRequired Then
        Dim d As New P1CallBack(AddressOf selectVisiblePanel_threadasko_Rd1)
        Me.Invoke(d, New Object() {})
    Else
        Me.RadDock1.Visible = True
    End If
End Sub

I would expect to get the .gif visible within the PictureBox in the new form I use but I just see it when the main form is created. When I click either of the buttons in the RadribbonBar I just see the panel but I do not see the PictureBox.

I make it work with simpler code in a simple application I use for fast debugging.

I would love if anyone could help me.

What I get

What I would like to get


Solution

  • I have found the answer to my problem. I opened new forms in panels. Each panel had 4-5 new forms in it. I wanted to show my panel with a pictureBox with a gif, while the other forms in background panel were loading.

    In WinForms you cannot use a backgroundWorker to load a form/panel in the doWork section, or in another thread the main thread is responsible for new forms. https://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker(v=vs.110).aspx

    I had to do a workaround and use the multithreading or backgroundworker in each form that was loaded in my panels. That way I show the picture box once for each form in the panel instead of 1 for all the forms in the panel.

    I hope some other can get help from my troubles.

    Example of working panel:

    Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        '''''''' Here I load my dtgas and dting that can take up to 2 min to load from DB. 
        Dim dtgas as System.Data.DataSet = loadFromDB(dataBeg, dataEnd)
        Dim dting as System.Data.DataSet = loadFromDB(dataBeg, dataEnd)
        Dim obj(1) As Object
        obj(0) = dtgas
        obj(1) = dting
        'System.Threading.Thread.Sleep(10000)
        e.Result = obj
        dtgas.Dispose()
        dting.Dispose()
    End Sub
    Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
        'get the answer from the dowork with e.result
        Dim r(1) As Object
        If e.[Error] IsNot Nothing Then
            Exit Sub
        End If
        r = e.Result
        If r IsNot Nothing Then
            Showradcharviewtotals(r(0), r(1))
        End If 'Make the RadChartView Visible and then the panel with the image not visible
        RCVListA.Visible = True
        Panel11.Visible = False
    End Sub
    

    In load or in a sub or function that is called from load:

    Private Sub CalledFromLoad_MyDataLoad()
        RCVListA.Visible = False
        Panel11.Dock = DockStyle.Fill
        Panel11.Visible = True
        BackgroundWorker1.RunWorkerAsync()
    End Sub