c#Progress Bar从另一个类调用方法

时间:2011-10-31 14:03:08

标签: c# winforms progress-bar

我试图通过将两个方法设为公共然后从另一个类调用方法来在WinForm上创建一个进度条(请参阅下面的代码示例)。但没有运气,酒吧不动。

以下是两个类:

namespace GP_Avantis_Integration
{
    //Class B
    public partial class GP_Avantis_Integration_Window : Form
    {
        public GP_Avantis_Integration_Window()
        {
            InitializeComponent();
        }

        DataSet ds = new DataSet();
        SqlDataAdapter sqlda = new SqlDataAdapter();
        SqlCommand sqlcomm = new SqlCommand();

        public static int recno;

        public void button1_Click(object sender, EventArgs e)
        {
            try
            {
                //Fetch data into memory

                //Fill in Header table

                //Fill in Line table

                //Cleaning open connection

                //Creating relationship in the Dataset between Header and Line table

                // Instantiating and Crearintg Header and Line source

                //Binding the Header source to the Header table

                //Binding the Line source to the relationship
            }

            catch (ApplicationException ae)
            {
            }

            finally
            {
            }
        }

        public void button2_Click(object sender, EventArgs e)
        {
            try
            {

                //Calling CreateJE Class
                //Class Method ProcessData
                CreateJE JE = new CreateJE(); --------> Calls the Class B
                JE.ProcessData(ds);
                MessageBox.Show("Complete!");
            }

            catch (ApplicationException ae)
            {
            }

            finally
            {
            }
        }

        public void progress_Bar_setup()
        {
            progressBar1.Minimum = 0;
            progressBar1.Maximum = CreateJE.max;
        }

        public void progressBar_updates(int recno)
        {
            progressBar1.Value = recno;
            progressBar1.Update();
        }
    }

    // Class B
    class CreateJE
    {
        static public int max;
        public void ProcessData (DataSet ds)
        {
            //Create an eConnect Trx type object
            //POPTransactionType po = new POPTransactionType();

            // ***** PO Header and Line 

            int ln;
            ln = 0;

            //Setting up ProgressBar
            int recno = 1;
            max = ds.Tables[0].Rows.Count;

            GP_Avantis_Integration_Window w = new GP_Avantis_Integration_Window();
            w.progress_Bar_setup();

            // Create an eConnect PO Header node object

            // Create an array for lineitems

            foreach (DataRow dtrHDR in ds.Tables["Header"].Rows)
            {
                //ProgressBar Updates
                w.progressBar_updates(recno);

                //Instantiating GetJE object 
                //Retrieves the next JE from GP

                //Create an eConnect PO Header node object

                //Add the header node to the trx type object

                ln = 0;

                foreach (DataRow dtrLine in dtrHDR.GetChildRows("HdrLine"))
                {
                    // Populate the elements of the taPoLIne_ItemsTaPOLine XML node

                    //Avantis Inv Trx Key

                    // Avantis GL Trx Type

                    //Add POLine to an Array

                    ln ++;
                }

                // Add the header node to the trx type object

                // Add the lineitem node to the trx type object

                // ***** Process information only

                // Create an eConnect document object

                // Create a file on the HD

                // Serialize using the XmlTextWriter to the file

                // Call the eConnectMethods
                // Separate Class

                // Instantiating the object for eConnectMethods class
                // Passing last JRNENTRY retreived using the GetJE class
                // so if there is an error on the eConnectEntry Method of     eConnectMethods Class
                // I can pass the last JE number back to GP

                recno++;
            }  
        }
    }
}

5 个答案:

答案 0 :(得分:0)

很难说出了什么问题。可能是max值未初始化,可能是update()方法没有重绘进度条。

还有一件事:使用BackgroundWorker可能会更好,因此您的UI不会锁定?这是一个例子:http://www.codeproject.com/Tips/83317/BackgroundWorker-and-ProgressBar-demo

答案 1 :(得分:0)

我认为您需要使用渲染优先级调用更新,如下所示:

 public void progressbar_updates(int recno)
 {
     Dispatcher.Invoke(new Action(() =>
     {
              progressbar1.Value += recno;
              progressbar1.UpdateLayout();
     }), DispatcherPriority.Render);
 }

答案 2 :(得分:0)

实施backgroundWorker并使用backgroundworker.ReportProgress更新进度条。然后它将在一个线程中实现您的代码,在另一个线程中实现UI。然后表单将响应更新。在读取和写入UI时要小心(因为它位于另一个中)当您启动Backgroundworker并在ReportProgress中写入时,请阅读UI。

C# Winform ProgressBar and BackgroundWorker

答案 3 :(得分:0)

使用背景工作者 这是最好的例子 Click here for BackGroundWorker

答案 4 :(得分:0)

我实施了一个“工人表单”,显示后台任务的进度。

这是我的代码(WorkerForm)

        #region Form
    private void frmLoader_Load(object sender, EventArgs e)
    {
                    if (OnExecute != null)
        {
            OnExecute(this, null);
        }
    }
    #endregion
    #region "Public"
    public void OnInitialize(object sender, EventArgs<String, int> e)
{
  if (pbLoader.InvokeRequired)
  {
    pbLoader.Invoke(new Action<object, EventArgs<String, int>>(OnInitialize), new Object[] { sender, e });
  }
  else
  {
    lblDynamicText.Text = e.Param1;
    pbLoader.Step = 1;
    pbLoader.Minimum = 1;
    pbLoader.Value = 1;
    pbLoader.Maximum = e.Param2;
  }
}
public void OnCreate(object sender, EventArgs<String> e)
{
  if (lblDynamicText.InvokeRequired)
  {
    lblDynamicText.Invoke(new Action<object, EventArgs<String>>(OnCreate), new Object[] { sender, e });
  }
  else
  {
    lblDynamicText.Text = e.Param1;
    pbLoader.PerformStep();
  }
}
public void OnFinished(object sender, EventArgs<String> e)
{
  if (lblDynamicText.InvokeRequired)
  {
    lblDynamicText.Invoke(new Action<object, EventArgs<String>>(OnFinished), new Object[] { sender, e });
  }
  else
  {
    lblDynamicText.Text = e.Param1;
  }
}

在我的演示者中(我使用的是ModelViewPresenter体系结构),我同时注入了对Winform和实际工作者类的引用。

 internal WorkerPresenter(IWorkerView WorkerView,IWorker ConcreteWorker)
{
  this.WorkerView = WorkerView;
  this.ConcreteWorker = ConcreteWorker;
  WorkerView.OnExecute += StartExecute;
}

在我的工人表单的表单加载事件期间引发了StartExecute。

private void StartExecute(Object sender, EventArgs e)
{
  ConcreteWorker.OnCreate += Create;
  ConcreteWorker.OnFinish += Finished;
  ConcreteWorker.OnInitialize += Initialize;
    var task = new Task<bool>(ConcreteWorker.Execute);
    task.Start();
    task.ContinueWith(c_task =>
    {
      ((frmWorker)WorkerView).DialogResult = System.Windows.Forms.DialogResult.OK;
    });
}

IWorker界面:

  public interface IWorker  {
event EventHandler<EventArgs<String>> OnCreate;
event EventHandler<EventArgs<String>> OnFinish;
event EventHandler<EventArgs<String, int>> OnInitialize;
bool Execute();

}

混凝土工人:OnInitialize =&gt;在进度条中设置文本和步骤数。 OnCreate =&gt;将步计数器递增1并设置另一个文本。 OnFinish =&gt;显示文本并再次关闭Worker表单。