Απο Winforms γενικά δεν είμαι και πολύ δυνατός. Ηθελα να φτιάξω λοιπον μια ωραία φορμίτσα που θα μου λέει "Please wait" όταν εγώ θα έτρεχα μια χρονοβόρα διαδικασία από πίσω...
Τελικα κατέληξα στη λύση του να βάλω τη διαδικασια σε ένα thread και να μιλάω μέσω ενός module με τη φόρμα χρησιμοποιώντας events.
Θα ήθελα να μου πείτε αν αυτή η λύση είναι πολύ "μπακάλικη", είναι ομως η μόνη απλή λύση που βρήκα για να έχω και "Please wait" και φορμα η οποία δεν "κολλάει" (hint, hint, εχει και animated εικονιδιάκι και ήθελα να ΚΑΝΕΙ animate το ατιμο :) )
Ριξτε μια ματια στον κώδικα, για τα σχόλια χρησιμοποιώ VBXC για να πάνε μετά στο nDoc. Δεν είναι τίποτα σπουδαίο, προχειρογραμμένο είναι, απλά για να μου πειτε αν το concept είναι ορθό. Καθε συμβουλή ευπρόσδεκτη!
'/// <summary>
'/// Starting point of the application.
'/// Presents a form to prompt the user for db login information, then starts
'/// executing a long-running procedure while presenting a "please wait" form.
'/// Finally, it presents the main application form.
'/// </summary>
Module mdlMain
'/// <summary>
'/// Holds the "Please wait" form instance
'/// </summary>
Private m_objFrmWait As frmPleaseWait
'/// <summary>
'/// Holds the connection string retrieved by the "Connect to" form
'/// </summary>
Private m_strConn As String
'/// <summary>
'/// Module starting point
'/// </summary>
Public Sub Main()
Dim strConn As String
Dim objFrmLogin As New frmLogin
'Add handlers for DbObjectManager events
AddHandler DbObjectManager.SPAnalysisStarted, AddressOf DBObjectManager_SpAnalysisStarted
AddHandler DbObjectManager.SPAnalyzed, AddressOf DbObjectManager_SpAnalyzed
AddHandler DbObjectManager.SPAnalysisEnded, AddressOf DBObjectManager_SpAnalysisEnded
'Show the login form
objFrmLogin.ShowDialog()
'Assuming that connection info is ok - the login form takes care of that
If objFrmLogin.DialogResult = DialogResult.OK Then
'Assign the connection string here
m_strConn = objFrmLogin.ConnectionString()
'Get rid of the stupid thing
objFrmLogin.Close()
objFrmLogin.Dispose()
'Create a thread to execute the long-running process and start it
Dim thrdGetData As New System.threading.Thread(AddressOf GetSPDefs)
thrdGetData.Start()
'Ok, the thread has started. For the sake of clarity, we don't have any
'code to catch Thread Abort exceptions, although we should.
'Now present the "please wait" form.
'As you can see, there's a progress bar updated by events thrown by
'DbObjectManager plus various other bullshit like an animated picture box etc.
m_objFrmWait = New frmPleaseWait
m_objFrmWait.ProgrBar.Value = 0
m_objFrmWait.ProgrBar.Visible = False
m_objFrmWait.PictureBox1.Refresh()
m_objFrmWait.lblSpName.Text = "Retrieving stored procedure definitions. Please wait..."
m_objFrmWait.lblSpName.Refresh()
'Show dialog so as not to let the execution halt here.
m_objFrmWait.ShowDialog()
End If
End Sub
<P class=source> '/// <summary>
'/// This is our thread. It executes the boring DB query stuff that takes a long time
'/// If you are curious to find out what it does, it creates a beautiful xml file
'/// containing all stored procedure dependencies in a database by analyzing the SP code
'/// not the sysdepends table. It takes quite a while, analyzing SPs one-by-one.
'/// </summary>
Private Sub GetSPDefs()
'Initialize the stupid thing - it's shared giati etsi mas aresei.
DbObjectManager.Initialize(m_strConn)
'Do the dirty work
DbObjectManager.GetData()
End Sub
'/// <summary>
'/// This is an event that shows that an SP has been analyzed. All it does is update
'/// the progress bar of the "please wait" form
'/// </summary>
'/// <param name="current">The number of the current stored procedure analyzed as compared to the total number of SPs to analyze</param>
'/// <param name="total">The total number of SPs to analyze</param>
'/// <param name="spName">The name of the specific SP</param>
Private Sub DbObjectManager_SpAnalyzed(ByVal current As Int32, ByVal total As Int32, ByVal spName As String)
m_objFrmWait.ProgrBar.Visible = True
m_objFrmWait.ProgrBar.Maximum = total + 1
m_objFrmWait.ProgrBar.Value = current
m_objFrmWait.lblSpName.Text = spName
m_objFrmWait.lblSpName.Refresh()
End Sub
'/// <summary>
'/// This used to do something, now it doesn't. Just kept it because I may find a
'/// use for it later on. Shows that the analysis has been started. What does that mean?
'/// Ok, a long-running query has been run before the analysis starts to gather all SPs and definitions
'/// ripping off the comments. This event shows that the query has ended and the analysis has started
'/// </summary>
Private Sub DBObjectManager_SpAnalysisStarted()
'Too lazy for now, maybe I'll work on it later
End Sub
'/// <summary>
'/// This is raised at the end of the long-running procedure.
'/// </summary>
Private Sub DBObjectManager_SpAnalysisEnded()
m_objFrmWait.Close()
'm_objFrmWait.Dispose() 'Kept making me mad, this one.
'Now show the main application form.
Dim objFrmMain As New frmMain(m_strConn)
objFrmMain.ShowDialog()
End Sub
End Module
Σωτήρης Φιλιππίδης
DotSee Web Services