Ladebalken bei Programmstart

exiter28

Erfahrenes Mitglied
Hallo Jungs!

Gibt es eine Möglichkeit, wenn die Form startet, die Ladezeit in einer
ProgressBar auszugeben?

Also das Load Ereignis der ersten Form, wenn diese hier ziemlich viel
laden muss, wird die Form ja nicht gleich angezeigt.

Evtl. eine Methode?

Besten Dank für Eure tipps!
 
Threads zum Beispiel.

Das ganze Laden in den Thread auslagern, das Loadevent beenden lassen und (Threadsichherheit nicht vergessen) den Fortschritt dem ursprüunglichen Thread mitteilen, der dann den Ladebalken anpasst.
 
danke für den Tipp!

habs jetzt so gelöst:

Load Ereignis der Form:

trd = New Thread(AddressOf ThreadTask)
trd.IsBackground = True
trd.Start()

Der Thread an sich:

Private Sub ThreadTask()

Dim size As Integer = 1 ' Variable für Ladebalken Maximum
Dim i As Integer ' Variable für For-Schleife
Me.TSPBar1.Value = 0 ' Ladebalken-Position = 0
Me.TSPBar1.Minimum = 0 ' Ladebalken-Minimum = 0

Me.TSPBar1.Maximum = size ' Ladebalken-Maximum

For i = 1 To size ' Beginn der For-Schleife
Me.TSPBar1.Value = i ' Ladebalken-Position der var. i zuweisen
Application.DoEvents() ' Windowswarteschlange unterbrechen
Thread.Sleep(300) ' Threadpause eileiten (300Msec.)

'
'
' hier kommt alles rein, was geladen werden soll (Load Ereignis)
'
'

Me.Cursor = Cursors.WaitCursor ' Cursor-Design = Warten
i += 1 ' Wert der var. i um 1 erhöhen
Next ' Ende der For-Schleife


Me.Cursor = Cursors.Default ' Cursor-Design = Standard
Me.TSPBar1.Value = 0 ' Ladebalken-Position = 0


End Sub

Das ganze funktioniert soweit, aber nur wenn ich die Anwendung NICHT im Debug-Modus starte.
Hier bekomme ich die Meldung:
"Ungültiger threadübergreifender Vorgang: Der Zugriff auf das Steuerelement erfolgte von einem anderen Thread als dem Thread, für den es erstellt wurde."

Weiss einer Rat?
 
Hmm ja,
.NET erlaubt Zugriffe auf GUI-Elemente nur in dem Thread, in dem sie auch erstellt wurden.

Hab ich in eigenen Programmen zwar schon ordentlich gemacht, muss aber selber nachschauen.

Bin erst wieder ca um 8 am Abend daheim; falls dann kein Anderer die Lösung schon gepostet hat schreib ich es dann.

edit: Das schaut ziemlich danach aus: http://weblogs.asp.net/rosherove/archive/2006/03/01/439309.aspx
if Invokerequired, dann invoke und ende; sonst weitermachen

Musst halt eine eigene Methode machen, die nur dafür da ist, den Ladebalken zu ändern
 
Zuletzt bearbeitet:
ich würd über eine dll nachdenken und diese abrufen. Die Zeit plus den ladebalken kannst du dann ja ganz easy zeichnen

und zwar mithilfe
Code:
Public Shared Sub ShowLoadingScreen()
	' Make sure it's only launched once.
	If ms_form IsNot Nothing Then
		Return
	End If
	ms_oThread = New Thread(New ThreadStart(LoadingScreen.ShowForm))
	ms_oThread.IsBackground = True
	ms_oThread.ApartmentState = ApartmentState.STA
	ms_oThread.Start()
End Sub
' A private entry point for the thread.
Private Shared Sub ShowForm()
	ms_form = New LoadingScreen()
	Application.Run(ms_form)
End Sub

Public Shared Sub CloseForm()
	If ms_form IsNot Nothing AndAlso ms_form.IsDisposed = False Then
		' Make it start going away.
		ms_form.m_dblOpacityIncrement = -ms_form.m_dblOpacityDecrement
	End If
	ms_oThread = Nothing
	' we don't need these any more.
	ms_form = Nothing
End Sub

' A static method to set the status and update the reference.
Public Shared Sub SetStatus(newStatus As String)
	SetStatus(newStatus, True)
End Sub

Public Shared Sub SetStatus(newStatus As String, setReference As Boolean)
	ms_sStatus = newStatus
	If ms_form Is Nothing Then
		Return
	End If
	If setReference Then
		ms_form.SetReference()
	End If
End Sub
Private Sub SetReference()
	If m_bDTSet = False Then
		m_bDTSet = True
		m_dtStart = DateTime.Now
		ReadIncrements()
	End If
	Dim dblMilliseconds As Double = ElapsedMilliSeconds()
	m_alActualTimes.Add(dblMilliseconds)
	m_dblLastCompletionFraction = m_dblCompletionFraction
	If m_alPreviousCompletionFraction IsNot Nothing AndAlso m_iIndex < m_alPreviousCompletionFraction.Count Then
		m_dblCompletionFraction = CDbl(m_alPreviousCompletionFraction(System.Math.Max(System.Threading.Interlocked.Increment(m_iIndex),m_iIndex - 1)))
	Else
		m_dblCompletionFraction = If((m_iIndex > 0), 1, 0)
	End If
End Sub

' Utility function to return elapsed Milliseconds
Private Function ElapsedMilliSeconds() As Double
	Dim ts As TimeSpan = DateTime.Now - m_dtStart
	Return ts.TotalMilliseconds
End Function
'reading the registry values
Private Sub ReadIncrements()
	Dim sPBIncrementPerTimerInterval As String = RegistryAccess.GetStringRegistryValue(REGVALUE_PB_MILISECOND_INCREMENT, "0.0015")
	Dim dblResult As Double

	If [Double].TryParse(sPBIncrementPerTimerInterval, System.Globalization.NumberStyles.Float, System.Globalization.NumberFormatInfo.InvariantInfo, dblResult) = True Then
		m_dblPBIncrementPerTimerInterval = dblResult
	Else
		m_dblPBIncrementPerTimerInterval = 0.0015
	End If

	Dim sPBPreviousPctComplete As String = RegistryAccess.GetStringRegistryValue(REGVALUE_PB_PERCENTS, "")

	If sPBPreviousPctComplete <> "" Then
		Dim aTimes As String() = sPBPreviousPctComplete.Split(Nothing)
		m_alPreviousCompletionFraction = New ArrayList()

		For i As Integer = 0 To aTimes.Length - 1
			Dim dblVal As Double
			If [Double].TryParse(aTimes(i), System.Globalization.NumberStyles.Float, System.Globalization.NumberFormatInfo.InvariantInfo, dblVal) Then
				m_alPreviousCompletionFraction.Add(dblVal)
			Else
				m_alPreviousCompletionFraction.Add(1.0)
			End If
		Next
	Else
		m_bFirstLaunch = True
		lblTimeRemaining.Text = ""
	End If
End Sub

' Method to store the intervals (in percent complete) from the current invocation
' to the registry.
Private Sub StoreIncrements()
	Dim sPercent As String = ""
	Dim dblElapsedMilliseconds As Double = ElapsedMilliSeconds()
	For i As Integer = 0 To m_alActualTimes.Count - 1
		sPercent += (CDbl(m_alActualTimes(i)) / dblElapsedMilliseconds).ToString("0.####", System.Globalization.NumberFormatInfo.InvariantInfo) & " "
	Next

	RegistryAccess.SetStringRegistryValue(REGVALUE_PB_PERCENTS, sPercent)

	m_dblPBIncrementPerTimerInterval = 1.0 / CDbl(m_iActualTicks)
	RegistryAccess.SetStringRegistryValue(REGVALUE_PB_MILISECOND_INCREMENT, m_dblPBIncrementPerTimerInterval.ToString("#.000000", System.Globalization.NumberFormatInfo.InvariantInfo))
End Sub
'********* Event Handlers ************

' Tick Event handler for the Timer control.  Handle fade in and fade out.  Also
' handle the smoothed progress bar.
Private Sub timer1_Tick(sender As Object, e As System.EventArgs)
	lblStatus.Text = ms_sStatus

	If m_dblOpacityIncrement > 0 Then
		m_iActualTicks += 1
		If Me.Opacity < 1 Then
			Me.Opacity += m_dblOpacityIncrement
		End If
	Else
		If Me.Opacity > 0 Then
			Me.Opacity += m_dblOpacityIncrement
		Else
			StoreIncrements()
			Me.Close()
			Debug.WriteLine("Called this.Close()")
		End If
	End If
	If m_bFirstLaunch = False AndAlso m_dblLastCompletionFraction < m_dblCompletionFraction Then
		m_dblLastCompletionFraction += m_dblPBIncrementPerTimerInterval
		Dim width As Integer = CInt(Math.Floor(pnlStatus.ClientRectangle.Width * m_dblLastCompletionFraction))
		Dim height As Integer = pnlStatus.ClientRectangle.Height
		Dim x As Integer = pnlStatus.ClientRectangle.X
		Dim y As Integer = pnlStatus.ClientRectangle.Y
		If width > 0 AndAlso height > 0 Then
			m_rProgress = New Rectangle(x, y, width, height)
			pnlStatus.Invalidate(m_rProgress)
			Dim iSecondsLeft As Integer = 1 + CInt(Math.Truncate(TIMER_INTERVAL * ((1.0 - m_dblLastCompletionFraction) / m_dblPBIncrementPerTimerInterval))) \ 1000
			If iSecondsLeft = 1 Then
				lblTimeRemaining.Text = String.Format("1 second remaining")
			Else
				lblTimeRemaining.Text = String.Format("{0} seconds remaining", iSecondsLeft)

			End If
		End If
	End If
End Sub

' Paint the portion of the panel invalidated during the tick event.
Private Sub pnlStatus_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs)
	If m_bFirstLaunch = False AndAlso e.ClipRectangle.Width > 0 AndAlso m_iActualTicks > 1 Then
		Dim brBackground As New LinearGradientBrush(m_rProgress, Color.FromArgb(14, 105, 168), Color.FromArgb(6, 38, 61), LinearGradientMode.Horizontal)
		e.Graphics.FillRectangle(brBackground, m_rProgress)
	End If
End Sub
 
Zurück