2012-01-14 11 views

risposta

10

Idealmente, ciò che si vuole fare è eseguire i controlli su un thread in background, in modo che il thread dell'interfaccia utente non sia bloccato. Dai un'occhiata alla classe BackgroundWorker.

È necessario collegare i controlli all'evento DoWork dell'operatore in background e chiamare il metodo RunWorkerAsync() di BackgroundWorker dall'evento Form_Load per avviare il lavoro in background.

Qualcosa di simile (nota, questo è testato):

BackgroundWorker bw = new BackgroundWorker(); 
public void Form_Load(Object sender, EventArgs e) { 
    // Show the loading label before we start working... 
    loadingLabel.Show(); 
    bw.DoWork += (s, e) => { 
     // Do your checks here 
    } 
    bw.RunWorkerCompleted += (s, e) => { 
     // Hide the loading label when we are done... 
     this.Invoke(new Action(() => { loadingLabel.Visible = false; })); 
    }; 
    bw.RunWorkerAsync(); 
} 
+0

perfetto. Grazie mille. ;) –

2

È possibile creare un altro thread per visualizzare il messaggio di caricamento.

Per prima cosa serve un bool.

bool loading = true; 

Creare un thread simile:

Thread myThread = new Thread(new ThreadStart(Loading)); 
myThread .Start(); 

Poi ha un metodo:

private void Loading() 
{ 
    while(loading) 
    { 
     //Display loading message here. 
    } 
} 

Quando hai finito di caricare qualunque sia sufficiente impostare il caricamento su false e il battistrada terminerà.

+0

Il thread dell'interfaccia utente rimarrà occupato mentre il ciclo non sarà in grado di mostrare qualsiasi cosa l'app annd si bloccherà. –

+0

No it wont. Questo è il punto del thread. – Axis

2

Dai un'occhiata al componente BackgroundWorker. Non hai bisogno di alcuna conoscenza di threading.

2

Ciò può essere ottenuto facilmente visualizzando un modulo separato eseguito su un altro thread. In questo modulo (chiamalo frmSplash) puoi inserire una gif animata o un testo statico. Il codice necessario è il seguente nel formato principale:

Dichiarare alcune variabili dopo la classe.

public partial class frmMain : Form 
{ 
    public Thread th1; 
    static frmSplash splash; 
    const int kSplashUpdateInterval_ms = 1; 

// Rest of code omitted 

Quindi aggiungere il seguente metodo al modulo principale. Questo avvia la schermata di avvio:

static public void StartSplash() 
{ 
    // Instance a splash form given the image names 
    splash = new frmSplash(kSplashUpdateInterval_ms); 

    // Run the form 
    Application.Run(splash); 
} 

Successivamente, è necessario un metodo per chiudere la schermata di avvio:

private void CloseSplash() 
{ 
    if (splash == null) 
     return; 

    // Shut down the splash screen 
    splash.Invoke(new EventHandler(splash.KillMe)); 
    splash.Dispose(); 
    splash = null; 
} 

Poi, nel vostro carico della forma principale, fare questo:

private void frmMain_Load(object sender, EventArgs e) 
{ 
    try 
    { 
     Thread splashThread = new Thread(new ThreadStart(StartSplash)); 
     splashThread.Start(); 

     // Set the main form invisible so that only the splash form shows 
     this.Visible = false; 

     // Perform all long running work here. Loading of grids, checks etc. 
     BindSalesPerson(); 
     BindCustomer(); 
     BindBrand(); 

     // Set the main form visible again 
     this.Visible = true; 
    } 
    catch (Exception ex) 
    { 
     // Do some exception handling here 
    } 
    finally 
    { 
     // After all is done, close your splash. Put it here, so that if your code throws an exception, the finally will close the splash form 
     CloseSplash(); 
    } 

} 

Quindi, se il modulo principale è chiuso, assicurati che la schermata iniziale sia chiusa anche:

Il codice per la forma Splash (In frmSplash.cs) è il seguente:

public partial class frmSplash : Form 
{ 

    System.Threading.Timer splashTimer = null; 
    int curAnimCell = 0; 
    int numUpdates = 0; 
    int timerInterval_ms = 0; 

    public frmSplash(int timerInterval) 
    { 
     timerInterval_ms = timerInterval; 

     InitializeComponent(); 
    } 


    private void frmSplash_Load(object sender, EventArgs e) 
    { 
     this.Text = ""; 
     this.MaximizeBox = false; 
     this.MinimizeBox = false; 
     this.ControlBox = false; 
     this.FormBorderStyle = FormBorderStyle.None; 
     this.Menu = null; 
    } 

    public int GetUpMilliseconds() 
    { 
     return numUpdates * timerInterval_ms; 
    } 

    public void KillMe(object o, EventArgs e) 
    { 
     //splashTimer.Dispose(); 

     this.Close(); 
    }   
} 

Spero che questo ti aiuta. Potrebbe non essere il miglior codice mai scritto, ma ha funzionato per me.

0

È necessario creare un modulo che si sta scaricando qui .. è necessario creare l'oggetto di tale modulo e chiamato utilizzando il concetto di threading..e in FrmLoading inserire una Picturebox e impostare l'immagine .gif al suo interno.

FrmLoading f2 = new FrmLoading(); 
using (new PleaseWait(this.Location,() =>MethodWithParameter())) {  f2.Show(this); } 
f2.Close(); 

Come mostrato sopra codice è necessario creare classe PleaseWait.

PleaseWait.cs

public class PleaseWait : IDisposable 
{ 
private FrmLoading mSplash; 
private Point mLocation; 

public PleaseWait(Point location, System.Action methodWithParameters) 
{ 
    mLocation = location; 
    Thread t = new Thread(new ThreadStart(workerThread)); 
    t.IsBackground = true; 
    t.SetApartmentState(ApartmentState.STA); 
    t.Start(); 
    methodWithParameters(); 
} 
public void Dispose() 
{ 
    mSplash.Invoke(new MethodInvoker(stopThread)); 
} 
private void stopThread() 
{ 
    mSplash.Close(); 
} 
private void workerThread() 
{ 
    mSplash = new FrmLoading(); // Substitute this with your own 
    mSplash.StartPosition = FormStartPosition.CenterScreen; 
    //mSplash.Location = mLocation; 
    mSplash.TopMost = true; 
    Application.Run(mSplash); 
} 
} 
Problemi correlati