С # 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++;
            }  
        }
    }
}

person Shazam    schedule 31.10.2011    source источник
comment
Что не так? Изменяется ли progessbar1.value во время отладки? В таком случае вам может потребоваться запустить цикл foreach в фоновом потоке.   -  person IanGilham    schedule 31.10.2011
comment
Вы не сможете вызвать свойство или метод подключения к классу B, используя ссылку на индикатор выполнения. Разместите фактический код, ваш пример кода, это даже не действительный код. В настоящее время, если вы не разместите код, который действительно может быть скомпилирован, вам ничем не помогут, пожалуйста, объясните, что именно не работает.   -  person Security Hound    schedule 31.10.2011
comment
Я устанавливаю min = 0, max = 2. Значения 1 и 2 передаются методу progressbar1.update () с использованием цикла foreach в классе B. При отладке я вижу передаваемые значения. Полоса прогресса (визуально) не двигается.   -  person Shazam    schedule 31.10.2011
comment
Я предполагаю, что вы где-то свою форму показываете? Код, который вы показываете выше для класса B, объявляет новый экземпляр WinForm, но, похоже, он не вызывает метод Show этой формы. Вы каким-то образом передаете экземпляр класса A в класс B? Кажется, что вы создаете новый экземпляр WinForm в классе B и пытаетесь обновить этот экземпляр вместо существующего. Но опубликованный вами код этого не показывает. Вот почему важно показать короткую, но полную программу, которую можно скомпилировать!   -  person Chris Dunaway    schedule 31.10.2011
comment
Я включил полный код с некоторыми правками. Надеюсь это поможет.   -  person Shazam    schedule 31.10.2011


Ответы (5)


Сложно сказать, в чем проблема. Возможно, значение max не инициализируется, возможно, метод update() не перерисовывает индикатор выполнения.

Еще одна вещь: может быть, лучше использовать BackgroundWorker, чтобы ваш пользовательский интерфейс не блокировался? Вот пример: http://www.codeproject.com/Tips/83317/BackgroundWorker-and-ProgressBar-demo

person Dmitry Polyanitsa    schedule 31.10.2011
comment
При отладке я получаю значения {value = 1, min = 0, max = 2} в progressbar1.update (). Кажется, что значения передаются правильно. - person Shazam; 31.10.2011

Я думаю, вам нужно вызвать обновление с приоритетом рендеринга, например:

 public void progressbar_updates(int recno)
 {
     Dispatcher.Invoke(new Action(() =>
     {
              progressbar1.Value += recno;
              progressbar1.UpdateLayout();
     }), DispatcherPriority.Render);
 }
person hcb    schedule 31.10.2011
comment
Диспетчер - WPF. ОП сказал, что использует WinForms. - person Joe White; 31.10.2011

Реализуйте backgroundWorker и используйте backgroundworker.ReportProgress для обновления индикатора выполнения. Затем он реализует ваш код в одном потоке, а пользовательский интерфейс - в другом. Тогда форма будет отвечать на обновления. Просто будьте осторожны, когда вы читаете и пишете в пользовательский интерфейс (потому что он находится в другой теме). Прочтите пользовательский интерфейс, когда вы запускаете Backgroundworker и записываете в ReportProgress.

C # Winform ProgressBar и BackgroundWorker

person Gerhard Powell    schedule 31.10.2011

Используйте backgrounworker.
Это лучший пример
Щелкните здесь для BackGroundWorker

person ravidev    schedule 18.11.2011

Я реализовал «рабочую форму», которая отображает ход выполнения фоновых задач.

Вот мой код (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 => Увеличивает счетчик шагов на единицу и устанавливает другой текст. OnFinish => отображает текст и снова закрывает форму Worker.

person Alex    schedule 18.11.2011