2011-10-31 53 views
0

我想通过使两个方法公开,然后从另一个类调用方法(请参阅我的代码示例下面)中的WinForm工作进度条。但没有运气,酒吧不动。c#从另一个类的进度条调用方法

这里有两类:

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++; 
      } 
     } 
    } 
} 
+0

出了什么问题? progessbar1.value是否在调试时更改?如果是这样,你可能需要在后台线程中启动foreach循环。 – IanGilham

+0

您将无法通过使用对进度栏的引用来调用连接到B类的属性或方法。发布实际的代码,您的示例代码,甚至不是有效的代码。此时,除非您发布实际可编译的代码,否则您无法获得帮助,请详细解释哪些内容无效。 –

+0

我在设置min = 0,max = 2。将1和2的值传递给progressbar1.update()方法,并在类B中使用foreach循环。调试时,我可以看到要传递的值。进度条(可视化)不移动。 – Shazam

回答

0

这很难说是什么问题。可能是max值未得到初始化,可能是update()方法不重绘进度条。

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

+0

调试时,我在progressbar1.update()上得到{value = 1,min = 0,max = 2}的值。所以看起来值正在被正确传递。 – Shazam

0

我认为你需要调用更新与渲染的优先级,这样的:

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

调度员是WPF。 OP表示他正在使用WinForms。 –

0

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

C# Winform ProgressBar and BackgroundWorker

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 =>设置文本和在你的进度条步骤的数量。 OnCreate =>将步进计数器加1并设置另一个文本。 OnFinish =>显示一个文本并再次关闭Worker窗体。