[VB.NET ]Label aanpassen tijdens map uitlezen

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • croontje
  • Registratie: April 2004
  • Laatst online: 26-07 00:34
Ik ben bezig met een soort van fuifmediaplayer. Nu lees ik tijdens mijn formload de muziekmappen uit en steek ik de bestandsnamen in een datagridview (ook artiest, title en dergelijke maar dat doet er niet toe).

Nu heb ik een spashscreen gemaakt en daarin een label gezet. Die label laat ik aanpassen in de loop die mijn mappen uitleest. Hier geeft VB.NET in DEBUG modus een fout:

Cross-thread operation not valid: Control 'lblloading' accessed from a thread other than the thread it was created on.

Het werkt zonder fout als ik de app normaal open, maar in debug geeft hij een fout. Volgens mij google kunsten is dit gewoon een veiligheid om brakke code te voorkomen en moet ik werken door een aparte thread te invoken. Nu ben ik al uren bezig met delegates, invoken links en rechts maar ik kom er niet uit.

Ik heb dus 2 forms: main en splash. In de main roep ik de subprocedure "dgSongsPrepareAndFill" op die de datagrid vult op de main form en terwijl een label aanpast op de splash.

Ik ben mijn oplossing aan het zoeken in de trend van:

code:
1
2
3
4
5
6
7
8
9
10
11
    Private Delegate Sub myLoadingLabelAdapter(ByVal text As String)

    Private Sub LoadingLabelAdapter(ByVal text As String)
        If frmSplash.lblLoading.InvokeRequired Then
            Dim d As New myLoadingLabelAdapter(AddressOf LoadingLabelAdapter)
            frmSplash.lblLoading.Invoke(d, text)
        Else
            frmSplash.lblLoading.Text = text
        End If

    End Sub


en dan oproepen in de dgSongsPrepareAndFill met:

LoadingLabelAdapter(filInfo.Name)

Kan iemand me hier even op het juiste pad zetten aub? _/-\o_

Indien je meer info nodig hebt dan geef ik dit natuurlijk graag.

Acties:
  • 0 Henk 'm!

  • gorgi_19
  • Registratie: Mei 2002
  • Nu online

gorgi_19

Kruimeltjes zijn weer op :9

.

[ Voor 98% gewijzigd door gorgi_19 op 03-11-2009 18:27 ]

Digitaal onderwijsmateriaal, leermateriaal voor hbo


Acties:
  • 0 Henk 'm!

  • croontje
  • Registratie: April 2004
  • Laatst online: 26-07 00:34
Nog even vermelden dat deze fout kan vermeden worden door de volgende regel aan te roepen in de form load maar dit wordt blijkbaar afgeraden omdat dit het probleem eigenlijk niet verhelpt maar gewoon negeert :s

Control.CheckForIllegalCrossThreadCalls = False

Acties:
  • 0 Henk 'm!

  • CMG
  • Registratie: Februari 2002
  • Laatst online: 10-12-2024

CMG

Wat als je in je frmSplash een functie maakt die UpdateLabel() heet en dat je het hoppen van threads daar doet? je myLoadingLableAdapter wordt dan een extra param (invoke 2e param omschrijven naar new Object() {text, d}

Veranderd dat nog wat?

Groet,

Nick.

NKCSS - Projects - YouTube


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:30
croontje schreef op dinsdag 03 november 2009 @ 18:30:
Nog even vermelden dat deze fout kan vermeden worden door de volgende regel aan te roepen in de form load maar dit wordt blijkbaar afgeraden omdat dit het probleem eigenlijk niet verhelpt maar gewoon negeert :s

Control.CheckForIllegalCrossThreadCalls = False
Dat is het probleem niet aanpakken, dat is gewoon je kop in het zand steken.


Over het probleem:
de oorzaak zit 'm er in dat je een windows control niet mag 'wijzigen' vanop een andere thread; je mag het enkel maar wijzigen vanaf de thread die die control gecreeërd heeft.
Je zal er dus moeten voor zorgen dat er een context switch gedaan wordt, en dat kan je idd doen mbhv 'Invoke'.
Ik weet niet hoe je code er nu uit ziet, dus veel kan ik er niet over zeggen over hoe je die nu best aanpast.
Wat je kan doen, is iedere keer dat je iets wilt aanpassen aan de UI tijdens je operatie die op een andere thread loopt, een event raisen. Je UI 'abboneert' zich op die event, en voert de gewenste actie uit (bv de inhoud van een label aanpassen).
Je taak die op een andere thread loopt, doet dan niets anders dan een event raisen die dus zegt dat er iets veranderd is. Je kan eventuele nodige informatie meeleveren met een EventArgs<T> type.
Bij het raisen van je event, kan je er zelf al voor zorgen, dat de eventhandler op de juiste thread uitgevoerd wordt:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
EventHandler ev = SomeEvent;

if( ev != null )
{
    ISynchronizeInvoke target = ev.Target as ISynchronizeInvoke;

   if( target != null && target.InvokeRequired )
   {
        target.Invoke ( ev, new object[] {this, EventArgs.Empty});
   }
   else
   {
         ev(this, EventArgs.Empty);
   }

}


Je kan het ook makkelijker doen, en eens kijken naar de BackGroundWorker class bv, die deze dingen al allemaal voor jou implementeert / abstraheert / wegstopt.

[ Voor 63% gewijzigd door whoami op 03-11-2009 22:17 ]

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • croontje
  • Registratie: April 2004
  • Laatst online: 26-07 00:34
Ik heb je uitleg een gelezen en snap ongeveer de bedoeling. De uitwerking moet ik nog eens bekijken, misschien dat dit mijn pet te boven gaat ;( . Je hebt duidelijk al een pak meer ervaring met die zaken. Ter illustratie zal ik een stuk code posten om beter te illustreren waarmee ik bezig ben.

Ik ga proberen om minder relevante code weg te laten en in woorden te zetten.

Onderstaande procedure wordt aangeroepen in de MAIN form load.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Public Sub dgSongsPrepareAndFill()
        Try
            'Leegmaken datagridview

            'aanmaken variabelen ID3 tag en fileinfo

            'nu ga ik dmv een for each elke map uitlezen die in mijn settings zitten e
            For Each dir As String In My.Settings.strArchive
                For Each fil As String In Directory.GetFiles(dir, "*", SearchOption.AllDirectories)
                    filInfo = New FileInfo(fil)

                    'enkel extensies die in de settings voorkomen
                    If My.Settings.strExtensions.IndexOf(filInfo.Extension) >= 0 Then
                        'Uitlezen ID3 Tags en rij toevoegen aan datagridview

'--------------------->Hier wil ik in mijn ander form de label updaten
                        frmSplash.lblLoading.Text = filInfo.Name

                    End If
                Next
            Next

            'datagridview verder aanpassen

        Catch ex As Exception
            writeLog("Error while loading songs: " & ex.Message)
        End Try


Ik heb je advies om de backgroundworker nader te bekijken opgevolgd en deze kleine maar duidelijke tutorial eens gevolgd
http://www.aena.nl/downloads/BackgroundworkerVB.pdf
Maar klopt het als ik denk dat ik enkel een getal kan rapporteren, dus een bepaald percentage en geen string?

Spijtig genoeg heb ik de code die ik eerst aan het testen was (met die invoke) verwijderd en mijn hele geschiedenis staat ondertussen vol met dergelijke site dus die code kan ik niet meer tonen.

Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
croontje schreef op woensdag 04 november 2009 @ 01:38:
Maar klopt het als ik denk dat ik enkel een getal kan rapporteren, dus een bepaald percentage en geen string?
De ReportProgress method heeft ook een overload waar je een object userState aan mee kan geven. Die krijg je in het ProgressChanged event ook weer mee, dus daar kan je status data ( in jouw geval een string ) meegeven.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:30
Die dgPrepareAndFill method wordt dus op een andere thread uitgevoerd ?
In plaats van jouw regel 17 -waar je dus direct je label aanpast-, zou ik daar dus een event raisen.
Jouw Splashform instance (frmSplash) subscribed op die event, en in die eventhandler zorg je er dan dus voor dat je label aangepast wordt.
Zo zou ik het doen. Op die manier heb je ook geen keiharde koppeling tussen die method en je splashform.
Zowiezo zou je die hele method naar een aparte class kunnen verhuizen (als dit al zo niet is).

Zo bv:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
public class LoadSongsTask
{
      private List<string> _songs = new List<string>();

      public ReadOnlyCollection Songs 
      {
             get { return _songs.AsReadOnly; }
      }

      public event EventHandler<MyEventArgs> ReportProgress;

      private ICollection<string> _directoriesToInspect;

      public LoadSongsTask( ICollection<string> directoriesToInspect )
      {
            _directoriesToInspect = directoriesToInspect;
      }

      public void Start()
      {
             Thread t = new Thread (new ThreadStart(DoWork));
             t.Start();
      }

      private void DoWork()
      {
             foreach( string dir in _directoriesToInspect )
             {
                   foreach( string file in Directory.GetFiles (dir, "*", .... );
                   {
                         // Do Stuff ....
                         OnProgressReport (new MyEventArgs (file));
                   }
             }
      }

      protected void OnProgressReport( MyEventArgs args )
      {
            EventHandler<MyEventArgs> handler = ReportProgress;

            if( handler != null )
            {
                 foreach( Delegate d in handler.GetInvocationList () )
                 {
                        ISynchronizeInvoke target = d.Target as ISynchronizeInvoke;

                        if( target != null && target.InvokeRequired )
                        {
                              target.Invoke (d, new object[] {this, args});
                        }
                        else
                        {
                              d.DynamicInvoke (this, args);
                        }
                 }
            }
      }
}


Je kan dan een instance van bovenstaande class maken, je zorgt ervoor dat je in je splash-form een eventhandler hangt aan de ReportProgress event. Die eventhandler kan er dus zo uit zien:
code:
1
2
3
4
private void LoadSongsTask_ReportProgress( object sender, MyEventArgs e )
{
     lblLoading.Text = e.FileName;
}


Als die 'taak' dan beëindigd is, dan kan je de Songs property van die LoadSongsTask gebruiken om je datagrid op te vullen.
(Om te weten wanneer je taak beëindigd is, dan zal je die class nog moeten uitbreiden met een extra event (Finished bv), die je raised wanneer je verwerking gedaan is.
Woy schreef op woensdag 04 november 2009 @ 09:09:
[...]

De ReportProgress method heeft ook een overload waar je een object userState aan mee kan geven. Die krijg je in het ProgressChanged event ook weer mee, dus daar kan je status data ( in jouw geval een string ) meegeven.
Dat is natuurlijk nog gemakkelijker. :P

[ Voor 6% gewijzigd door whoami op 04-11-2009 09:16 ]

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • Mastermind
  • Registratie: Februari 2000
  • Laatst online: 01-09 22:18
Je moet inderdaad Invoke gebruiken.
frmSplash.lblLoading.Text = filInfo.Name
vervangen door (zelf even vertalen naar Visual Basic):

C#:
1
2
3
4
5
6
7
8
9
10
  frmSplash.lblLoading.Invoke(new lblLoadingCallback(UpdateLblLoading), 
          new object[] {filInfo.Name});
  //..
}

private delegate void  lblLoadingCallback(string name);
private void UpdateLblLoading(string name)
{
   frmSplash.lblLoading.Text = name;
}


Je zou de object-array kunnen uitbreiden met meer properties die op het label veranderd moeten worden.

Acties:
  • 0 Henk 'm!

  • croontje
  • Registratie: April 2004
  • Laatst online: 26-07 00:34
Woy schreef op woensdag 04 november 2009 @ 09:09:
[...]

De ReportProgress method heeft ook een overload waar je een object userState aan mee kan geven. Die krijg je in het ProgressChanged event ook weer mee, dus daar kan je status data ( in jouw geval een string ) meegeven.
Dit heb ik gisteren dus geprobeerd maar er lijkt toch nog iets mis te lopen.
Ik heb een background worker toegevoegd. In de formload waar ik normaal de dgSongsPrepareAndFill aanroep start ik nu de backgroundworker met: BackgroundWorker1.RunWorkerAsync()

Vervolgens heb ik in de DoWork het volgnede gezet:
code:
1
2
3
4
    Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        Dim worker As System.ComponentModel.BackgroundWorker = CType(sender, System.ComponentModel.BackgroundWorker)
        dgSongsPrepareAndFill(worker, e)
    End Sub


En op de progress changed:

code:
1
2
3
    Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As System.Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
        frmSplash.lblLoading.Text = e.UserState.ToString
    End Sub


Op de plaats in dgSongsPrepareAndFill waar ik normaal mijn label update heb ik nu hetvolgende gezet:
pWorker.ReportProgress(30, filInfo.Name)
(die 30 heb ik er maar ingezet, ik heb toch nog geen percentage nodig dus dat maakt me niet veel uit)

Het stuk code van Mastermind heb ik eens getest maar daar maak ik blijkbaar steeds een fout bij deze regel:
frmSplash.lblLoading.Invoke(new lblLoadingCallback(UpdateLblLoading), new object[] {filInfo.Name});

de post van whoami moet ik straks nog eens grondig bekijken dan dat is geen slappe kost :)

Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
croontje schreef op woensdag 04 november 2009 @ 14:22:
[...]
Dit heb ik gisteren dus geprobeerd maar er lijkt toch nog iets mis te lopen.
Wat gaat er dan mis? Heb je al eens een break-point op de volgende regel gezet? En word die ook aangeroepen? Heeft UserState dan de juiste waarde?

Visual Basic .NET:
1
        frmSplash.lblLoading.Text = e.UserState.ToString
Het stuk code van Mastermind heb ik eens getest maar daar maak ik blijkbaar steeds een fout bij deze regel:
frmSplash.lblLoading.Invoke(new lblLoadingCallback(UpdateLblLoading), new object[] {filInfo.Name});
Dan is weer de vraag wat gaat er mis
de post van whoami moet ik straks nog eens grondig bekijken dan dat is geen slappe kost :)
Het concept is vrij eenvoudig, je kijkt bij een eventhandler of het target geinvoked moet worden ( Dan implementeerd hij de interface ISynchronizeInvoke ), en als dat zo is, dan Invoke ( het aanroepen in een andere thread ) je de event-handler in de juiste context. Anders kan je hem gewoon in je eigen context aanroepen. Echter denk ik dat het belangrijk is dat je eerst duidelijk snapt waarom de foutmelding in eerste instantie gegooid word, en waarom dat opgelost word met Invoke/Backgroundworker/etc..

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • CodeIT
  • Registratie: Juni 2002
  • Laatst online: 09-09 22:04

CodeIT

Code IT

Dit lijkt me goed moeten gaan. Heb je de property WorkerReportsProgress (http://msdn.microsoft.com...orkerreportsprogress.aspx) van de bgw wel op true gezet?

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:30
croontje schreef op woensdag 04 november 2009 @ 14:22:
[...]


Dit heb ik gisteren dus geprobeerd maar er lijkt toch nog iets mis te lopen.
Ik heb een background worker toegevoegd. In de formload waar ik normaal de dgSongsPrepareAndFill aanroep start ik nu de backgroundworker met: BackgroundWorker1.RunWorkerAsync()

Vervolgens heb ik in de DoWork het volgnede gezet:
code:
1
2
3
4
    Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        Dim worker As System.ComponentModel.BackgroundWorker = CType(sender, System.ComponentModel.BackgroundWorker)
        dgSongsPrepareAndFill(worker, e)
    End Sub
Waarom geef je de backgroundworker zelf ook weer mee aan je dgSongsPrepareAndFill ?
Op de plaats in dgSongsPrepareAndFill waar ik normaal mijn label update heb ik nu hetvolgende gezet:
pWorker.ReportProgress(30, filInfo.Name)
(die 30 heb ik er maar ingezet, ik heb toch nog geen percentage nodig dus dat maakt me niet veel uit)
en wat gaat er dan nog fout ?

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • croontje
  • Registratie: April 2004
  • Laatst online: 26-07 00:34
Ik kom er even niet aan om verder te werken wegens werkdrukte. Volgende week ga ik het nog eens bekijken dus denk aub niet dat ik jullie raad in de wind sla :p

  • croontje
  • Registratie: April 2004
  • Laatst online: 26-07 00:34
Hoi ik ben weer even bezig geweest. Ik heb dus een test app gemaakt om wat te experimenteren met die background worker. En op die manier hoop ik eruit te komen.
Deze test app doet slechts 1 ding. Het vult een listbox met de bestanden in een map. Als test heb ik ook een progresbar toegevoegd en een label om de bestanden die door de loop gaan te bekijken.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Imports System
Imports System.IO
Imports System.Threading

Public Class frmPartyPlayer
    Dim test As Integer

    Private Sub frmPartyPlayer_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        BackgroundWorker1.RunWorkerAsync()
    End Sub

    Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        Dim filecount, counter As Integer
        filecount = System.IO.Directory.GetFiles("d:\Music").Length()
        counter = 1

        For Each fil As String In Directory.GetFiles("d:\Music")
            BackgroundWorker1.ReportProgress(CInt((100 * counter) / filecount), fil)
            counter += 1
            Thread.Sleep(10)
        Next
    End Sub

    Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
        Label1.Text = e.UserState.ToString
        ProgressBar1.Value = e.ProgressPercentage
        ListBox1.Items.Add(e.UserState)
    End Sub
End Class


Dit werkt perfect. De listbox zie ik mooi vullen. De progressbar loopt vol en de label wijzigt. (die sleep heb ik erbij gezet om het proces wat te vertragen).

Het probleem:
Ik heb een splashscreen toegevoegd met een label op. Als ik vervolgens de app open dan zie ik de splash screen verschijnen. Na een tijdje verdwijnt hij en zie ik het main form nog verder vullen. Geen exception.
Voeg ik echter volgende regel toe in de background worker progress changed:
code:
1
frmSplash.lblLoading.Text = e.UserState.ToString


Dan krijgt ik als exception:
Exception has been thrown by the target of an invocation.
met als inner exception:
{"Cross-thread operation not valid: Control 'lblLoading' accessed from a thread other than the thread it was created on."}

Uit de uitleg van whoami maak ik op dat ik nu best, ipv de text van die label te setten in de progress changed, in de progress changed een event raise van het splashscreen met de filename als argument en vervolgens in dat event de label aanpas.

Zit ik tot zover al goed?

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Je moet ervoor zorgen dat de frmSplash.lblLoading.Text gezet word in de thread als dat dat object gecreëerd is. Een event raisen zorgt er in principe niet voor dat je van thread veranderd.

Geef nu eens eenvoudig aan welke UI elementen je nu hebt, en op wat voor manier die gemaakt worden, en aangeroepen worden?
offtopic:
met [code=vb.net] krijg je ook code highlighting, dat maakt de code wat beter leesbaar

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • creator1988
  • Registratie: Januari 2007
  • Laatst online: 11-09 14:44
Die Control.CheckFor blabla werkt overigens niet als je in C# een release build maakt van je assembly

Acties:
  • 0 Henk 'm!

  • croontje
  • Registratie: April 2004
  • Laatst online: 26-07 00:34
Woy schreef op donderdag 12 november 2009 @ 13:16:
Geef nu eens eenvoudig aan welke UI elementen je nu hebt, en op wat voor manier die gemaakt worden, en aangeroepen worden?
Wat UI elementen betreft heb ik het volgende:

frmPartyplayer met een listbox, label en progressbar
frmSplash met een label

De enige code die ik gebruik is die ik ik reeds postte, namelijk de volgende (met kleur :p )

Visual Basic .NET:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
Imports System
Imports System.IO
Imports System.Threading

Public Class frmPartyPlayer
    Dim test As Integer
    Private WithEvents splash As frmSplash

    Private Sub frmPartyPlayer_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        BackgroundWorker1.RunWorkerAsync()
    End Sub

    Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        Dim filecount, counter As Integer
        filecount = System.IO.Directory.GetFiles("d:\Music").Length()
        counter = 1

        For Each fil As String In Directory.GetFiles("d:\Music")
            BackgroundWorker1.ReportProgress(CInt((100 * counter) / filecount), fil)
            counter += 1
            Thread.Sleep(10)
        Next
    End Sub

    Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
        frmSplash.lblLoading.Text = e.UserState.ToString

        Label1.Text = e.UserState.ToString
        ProgressBar1.Value = e.ProgressPercentage
        ListBox1.Items.Add(e.UserState)
    End Sub
End Class


Ik ga nu onmiddelijk mijn testproject even uploaden indien u interesse heeft om het naderbij te bekijken is dit dus mogelijk.

Het zipje is hier te downloaden

Acties:
  • 0 Henk 'm!

  • croontje
  • Registratie: April 2004
  • Laatst online: 26-07 00:34
Niemand meer? :s

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:30
Ik vind dat je heel vies bezig bent.

In je frmPartyPlayer ga je rechtstreeks de controls die op je splash screen staan, gaan aanpassen. :X
Je zegt dat je splashscreen plots verdwijnt, maar, ik zie niet waar je die splash toont, noch waar je 'm sluit ? (Sluiten zou ik doen als je backgroundworker gedaan heeft met wat hij moet doen).

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • croontje
  • Registratie: April 2004
  • Laatst online: 26-07 00:34
In de code van mijn test app staat inderdaad geen splashscreen. Ik citeer mezelf even ;)
Het probleem:
Ik heb een splashscreen toegevoegd met een label op. Als ik vervolgens de app open dan zie ik de splash screen verschijnen. Na een tijdje verdwijnt hij en zie ik het main form nog verder vullen. Geen exception.
Voeg ik echter volgende regel toe in de background worker progress changed:

frmSplash.lblLoading.Text = e.UserState.ToString

Dan krijgt ik als exception:
Exception has been thrown by the target of an invocation.
met als inner exception:
{"Cross-thread operation not valid: Control 'lblLoading' accessed from a thread other than the thread it was created on."}
Ivm de "viesheid" van de code, spijtig genoeg heb ik geen ervaring met "echte" programma's maken. Ik kan programmeren maar enkel van die domme schoolvoorbeelden. Echte regels heb ik nooit geleerd dus in dit programma doe ik ook wat ik denk dat juist/een goede manier is. Daarom excuses voor de bagger code.

Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Je SplashScreen is een view op de state van je backgroundworker. Laat je SlashScreen dan ook subscriben op het ProgressChanged event van die backgroundworker. In die eventhandler kan je dan je label aanpassen.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • croontje
  • Registratie: April 2004
  • Laatst online: 26-07 00:34
Ik heb wat gegoogled en merk dat ik met Addhandler kan subscriben op een event.
http://www.java2s.com/Tut...monstrationAddHandler.htm

Ik weet echter niet goed hoe ik hiermee verder moet. Eerst een nieuwe instantie maken van de splashscreen met "Private WithEvents splash As New frmSplash" en "splash = New frmSplash" en vervolgens die Addhandler toevoegen? En dit alles in de formload van mijn partyplayer form?

Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
croontje schreef op woensdag 18 november 2009 @ 11:47:
Ik heb wat gegoogled en merk dat ik met Addhandler kan subscriben op een event.
http://www.java2s.com/Tut...monstrationAddHandler.htm

Ik weet echter niet goed hoe ik hiermee verder moet. Eerst een nieuwe instantie maken van de splashscreen met "Private WithEvents splash As New frmSplash" en "splash = New frmSplash" en vervolgens die Addhandler toevoegen? En dit alles in de formload van mijn partyplayer form?
Je zult er voor moeten zorgen dat je in frmSplash een refferentie hebt naar de bacgroundworker waar je data van wilt tonen, daarna kun je in frmSplash inderdaad met addHandler subsriben voor een event.

Zomaar een nieuwe frmSplash gaan declareren/instantieren en daar een event aan koppelen gaat je probleem in ieder geval niet oplossen.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”

Pagina: 1