2011-12-09 3 views
10

Desidero informare l'utente mentre i dati vengono letti da un database SQL e ho deciso di creare un modulo con una barra di avanzamento ma non funziona, forse perché è necessario un thread . Voglio creare il modulo al livello di programmazioneVisualizzazione di una barra di avanzamento durante l'esecuzione di una query SQL

 ProgressBar pb = new ProgressBar(); 

     pb.MarqueeAnimationSpeed = 30; 
     pb.Style = ProgressBarStyle.Marquee; 
     pb.Dock = DockStyle.Fill; 

     progressForm.ClientSize = new Size(200, 50); 
     progressForm.FormBorderStyle = FormBorderStyle.FixedDialog; 
     progressForm.StartPosition = FormStartPosition.CenterScreen; 
     progressForm.Controls.Add(pb); 
     progressForm.ControlBox = false; 
     progressForm.TopMost = true; 

     progressForm.Show(); 
     //do data processes here (all queries and executes) 
     progressForm.close(); 

Come si modifica il codice sopra per raggiungere gli obiettivi dichiarati?

modifica: Btw, voglio utilizzare questa forma di barra di avanzamento in tutte le funzioni di dati nel mio progetto. Ad esempio: fillGrid, runQuery ..

@Grazie mille per le vostre risposte. Volevo dire come posso usare una funzione di classe, per esempio la mia funzione gridFill è in quella classe di connessione:

class ConnectionClass 
    { 
     public static SqlConnection connection = new SqlConnection(); 

    public string sorgu; 
    public static string server; 
    public static string userId; 
    public static string catalog; 
    public static string password; 
    public static string accessMethod; 
    public DataSet ds = new DataSet(); 
    Form progressForm = new Form();  

    public bool Open() 
    { 
     try 
     { 
      if (connection.State != ConnectionState.Open) 
      { 

       connection.ConnectionString = "Data Source = " + server + ";" + 
               "Initial Catalog=" + catalog + ";" + 
               "User ID=" + userId + ";" + 
               "Password=" + password + ";" + 
               "Connect Timeout=0"; 

       connection.Open(); 
       return true; 
      } 
      else 
      { 
       return true; 
      } 


     } 
     catch (Exception ex) 
     { 
      MessageBox.Show("System message:" + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 
      return false; 
     } 

    } 

    public DataTable Dt(string query) 
    { 
     DataTable dt = new DataTable(); 
     if (Open()) 
     { 
      SqlDataAdapter da = new SqlDataAdapter(query, connection); 
      try 
      { 
       //progressForm.Showdialog() is this possible??? 
       da.Fill(dt); 
       //progressForm.close(); ?? 
      } 
      catch (Exception ex) 
      { 
       MessageBox.Show("Sistem Mesajı:" + ex.Message, "Hata", MessageBoxButtons.OK, MessageBoxIcon.Error); 
      } 
     }   
     return dt; 
    } 

    public bool Run(string query, string hataMsj) 
    { 
     Form activeForm = Form.ActiveForm; 
     query = " SET DATEFORMAT DMY " + query; 

     SqlCommand sc = new SqlCommand(query, connection); 
     try 
     { 
      Open(); 
      sc.ExecuteNonQuery(); 
      return true; 
     }   
     catch (Exception) 
     { 
      return false; 
     } 
    } 

    public void fillComboBox(string sorgu, ComboBox cb, string text, string value) 
    { 
     DataTable dt = Dt(sorgu); 

     cb.DisplayMember = text; 
     cb.ValueMember = value; 
     cb.DataSource = dt; 
     if (cb.Items.Count > 0) 
     { 
      cb.SelectedIndex = 0; 
     } 

    } 

    public int fillGridView(string sorgu, DataGridView dgv) 
    { 
     DataTable dtGrvw = Dt(sorgu); 
     dgv.DataSource = dtGrvw; 
     return 1; 
    }  
    } 

e esempi di query da un'altra forma (classe)

ConnectionClass cc = new ConnectionClass(); 

    query= " INSERT INTO tblPersonel (" + 
              " [sqlUserName] " + 
              ",[personelNo] " + 
              ",[ad] " + 
              ",[soyad] " + 
              ",[departmanId] " + 
              ",[emailadres] " + 
              ",[tcKimlikNo],[kangurubu],[dokumaciNo])VALUES" + 
              "('" + tbSqlUserName.Text + 
              "','" + tbPersonelNo.Text + 
              "','" + tbAd.Text + 
              "','" + tbSoyad.Text + 
              "','" + cbDepartman.SelectedValue.ToString() + 
              "','" + tbMail.Text + 
              "','" + tbKimlikno.Text + 
              "','" + tbKangrubu.Text + 
              "','" + tbDokumaciNo.Text + "') "; 
        if (cc.Run(query, "Unexpected error on insert new person")) 
        { 
         fillGrid(); 
         this.Close(); 

        } 

    public void fillGrid() 
    { 
     query= " select * from View_Personel order by personelNo desc"; 
     cc.fillGridView(query, gridviewPersonel); 
    } 

e non posso immaginare come può Lo uso nell'evento bw_DoWork. perché la mia funzione ha parametri. (query, gridview) quando la chiamo da un'altra classe posso usarla con parametri ...

p.s. : this Method è abbastanza buono per me ma non ha funzionato. Non ho capito il problema

+7

Esaminare la classe del lavoratore in background. http://msdn.microsoft.com/en-us/library/cc221403(v=vs.95).aspx –

risposta

3

Usa la classe BackgroundWorker per riempire il tuo DataGrid.

 Form progressForm; 

    public void func() { 
     BackgroundWorker bw = new BackgroundWorker(); 
     bw.DoWork += new DoWorkEventHandler (bw_DoWork); 
     bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler (bw_RunWorkerCompleted); 

     progressForm = new Form(); 

     ProgressBar pb = new ProgressBar(); 

     pb.MarqueeAnimationSpeed = 30; 
     pb.Style = ProgressBarStyle.Marquee; 
     pb.Dock = DockStyle.Fill; 

     progressForm.ClientSize = new Size (200, 50); 
     progressForm.FormBorderStyle = FormBorderStyle.FixedDialog; 
     progressForm.StartPosition = FormStartPosition.CenterScreen; 
     progressForm.Controls.Add (pb); 
     progressForm.ControlBox = false; 
     progressForm.TopMost = true; 

     progressForm.Show(); 

     string queryString = "SELECT ...."; // fill query string here 
     var params = new KeyValuePair<GridControl, string>(sorgu, queryString); 
     bw.RunWorkerAsync (params); 
    } 

    void bw_DoWork (object sender, DoWorkEventArgs e) { 
     KeyValuePair<GridControl, string> params = e.Argument as KeyValuePair<GridControl, string>; 
     ConnectionClass cc = new Connection Class(); 
     cc.fillGrid(params.Value, params.Key); 
    } 

    void bw_RunWorkerCompleted (object sender, RunWorkerCompletedEventArgs e) { 
     progressForm.Close(); // 
    } 

È possibile inviare un parametro a BackgroundWorker. Se hai bisogno di più di un parametro, puoi inviare una Tupla che contiene gli oggetti di cui hai bisogno.

MODIFICA: Se si è su 3.5, è possibile utilizzare KeyValuePair. Il codice è aggiornato per quello.

+0

grazie per il tuo commento funziona bene. ma ho un piccolo problema la mia funzione di riempimento dei dati è in una classe e prende 2 parametri (query e gridcontrol) e la uso ovunque nel mio progetto public void fillGridControl (stringa sorgu, GridControl gc) { BindingSource dataSource = new BindingSource (Dt (sorgu) , nullo); gc.DataSource = dataSource; } posso inserire questa funzione nell'evento bw_DoWork? – Rapunzo

+1

@Rapunzo Puoi semplicemente chiamare la tua funzione fillGridControl dall'interno dell'evento bw_DoWork. Non conosco il tuo codice, ma c'è qualche ragione per cui questo non funzionerà? – Will

+0

Ho aggiornato la mia risposta sopra. – Will

0

Proprio come Ash Burlaczenko consigliato, sarà necessario utilizzare uno BackgroundWorker per tale scopo.

Dal momento che, tuttavia, ti piacerebbe legarlo con un ProgressBar, ti consiglio di guardare questo articolo su CodeProject: ProgressWorker.

È abbastanza facile da usare e aggiorna automaticamente la barra di avanzamento. Tutto quello che dovrai fare è ricordare di chiamare il metodo ProgressWorker.ReportProgress di volta in volta per aggiornare la barra di avanzamento associata.