Gui update from another C # class

Hey, I'm new to C # plz help. I am writing a program that sorts data in a file, and this is a time-consuming process, so I thought that I should run it in a separate thread, and since it has many steps, so I created a new class for it. the problem is that I want to show progress in the main GUI, and I know that I should use the Invoke function, but the problem is that form control variables are not available for this class. what should I do??????

code example:

public class Sorter
{
    private string _path;
    public Sorter(string path)
    {
        _path = path;
    }

    public void StartSort()
    {
        try
        {
                 processFiles(_path, "h4x0r"); // Just kidding
        }
        catch (Exception e)
        {
            MessageBox.Show("Error: " + e.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }

    private void processFiles(string Dir, string[] key)
    {
        /* sorting program */

    }

and used as

    public partial class Form1 : Form
    {
        Sorter sort;
        public Form1()
        {
            InitializeComponent();
        }

        private void browseBtn_Click(object sender, EventArgs e)
        {
            if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
                textBox1.Text = folderBrowserDialog1.SelectedPath;
        }

        private void startBtn_Click(object sender, EventArgs e)
        {
            if (startBtn.Text == "Start Sorting")
            {
   Thread worker = new Thread(new ThreadStart(delegate() {
                sort = new Sorter(textBox1.Text);
                sort.StartSort(); })); 
                worker.start();
            }
            else
                MessageBox.Show("Cancel");//TODO: add cancelling code here
        }
    }

Help plz.

+3
source share
4 answers

, , . .

. ProgressEventArgs - , EventArgs Integer .

// delegate to update progress
public delegate void ProgressChangedEventHandler(Object sender, ProgressEventArgs e);

// Event added to your worker class.
public event ProgressChangedEventHandler ProgressUpdateEvent

// Method to raise the event
public void UpdateProgress(object sender, ProgressEventArgs e)
{
   ProgressChangedEventHandler handler;
   lock (progressUpdateEventLock)
   {
      handler = progressUpdateEvent;
   }

   if (handler != null)
      handler(sender, e);
}
+4

BackgroundWorker. , , , .

    public Form1()
    {
        InitializeComponent();

        backgroundWorker.WorkerReportsProgress = true;
        backgroundWorker.WorkerSupportsCancellation = true;
        backgroundWorker.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker_ProgressChanged);
    }

    void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        progressBar1.Value = e.ProgressPercentage;
    }

    private void btnStart_Click(object sender, EventArgs e)
    {
        if (!backgroundWorker.IsBusy)
            backgroundWorker.RunWorkerAsync();
    }

    private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        for (int i = 1; i < 101; ++i)
        {
            if (backgroundWorker.CancellationPending)
            {
                e.Cancel = true;
                break;
            }
            else
            {
                //Sort Logic is in here.
                Thread.Sleep(250);
                backgroundWorker.ReportProgress(i);
            }
        }
    }

    private void btnCancel_Click(object sender, EventArgs e)
    {
        if (backgroundWorker.IsBusy && backgroundWorker.WorkerSupportsCancellation)
            backgroundWorker.CancelAsync();
    }
+2

- :

public delegate void StatusReporter(double progressPercentage);

public class MainClass
{

    public void MainMethod()
    {
        Worker worker = new Worker(ReportProgress);

        ThreadStart start = worker.DoWork;
        Thread workThread = new Thread(start);

        workThread.Start();

    }

    private void ReportProgress(double progressPercentage)
    {
        //Report here!!!
    }
}


public class Worker
{
    private readonly StatusReporter _reportProgress;

    public Worker(StatusReporter reportProgress)
    {
        _reportProgress = reportProgress;
    }

    public void DoWork()
    {
        for (int i = 0; i < 100; i++ )
        {
            // WORK, WORK, WORK
            _reportProgress(i);
        }
    }
}
+1

. Invoke, .

...

  • ... , , , - ( , , .. )
  • ... save the method as a method in your form and pas to start a new thread (after all, the new thread should not start in another class)
  • ... change the access modifiers on your controls to be (say) internalsuch that any class within the same assembly can Invokemodify or read controls.
  • ... make your working class a child of the form that it needs to access - then it can see privateits parent if it is passed a reference to the instance.
+1
source

Source: https://habr.com/ru/post/1796275/


All Articles