tedhan
tedhan

Reputation: 73

How to ReportProgress multiple values?

I am trying to send an array in a single DoWork, but in ReportProgress, there is no way to receive an array, I'm not sure what should I do to be able to pass a array, really appreciate if anyone has any idea.

This is what I was trying to do:

public void backgroundWorkerXY_DoWork(object sender, DoWorkEventArgs e)
    {
        do
        {
            X = -(RSSI_PI1_ST1);
            Y = -(RSSI_PI1_ST1) + 5;
            backgroundWorkerX.ReportProgress(X,Y); // pass X and Y

            Thread.Sleep(50);
        } while (true);
    }

Then here to pass these two values to change the locations of a image:

    public void backgroundWorkerXY_ProgressChanged(object sender, object sender1, ProgressChangedEventArgs e)
    {
        pictureBox1.Location = new Point((int.Parse(e.ProgressPercentage.ToString())), (int.Parse(e.ProgressPercentage.ToString())) );
    // Not sure how to let a single ProgressChanged to send two values here
    }

There is an alternative way to do it is to separate them, for example, pass X, and pass Y, but to change a location of image, the values must be a Point contains 2 values (what I discovered so far, may not be correct), so I am assuming it has to be in a single ProgressChanged,

This is what I also tried

pictureBox1.Location.X = new Point((int.Parse(e.ProgressPercentage.ToString())));

However it said "CS1612 Cannot modify the return value of 'Control.Location' because it is not a variable"

What I am trying to do is to change the location for both X and Y, I am really welcome to any alternative solutions, really appreciate any ideas or thoughts!

Upvotes: 3

Views: 2967

Answers (3)

Vignesh.N
Vignesh.N

Reputation: 2666

the ReportProgress has an overload which accepts any object, you can use that.

worker.ReportProgress( someProgressPercentage, new Point(x,y));

private void  backgroundWorkerXY_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    var point = (Point)e.UserState;
    pictureBox1.Location = point;
}

Upvotes: 2

Adnan Umer
Adnan Umer

Reputation: 3689

ReportProgress accepts second argument as object. You can use that to either return a custom datatype or simply use Tuple.

public void backgroundWorkerXY_DoWork(object sender, DoWorkEventArgs e)
{
    do
    {
        X = -(RSSI_PI1_ST1);
        Y = -(RSSI_PI1_ST1) + 5;
        backgroundWorkerX.ReportProgress(50, new Tuple<int, int>(X,Y));

        Thread.Sleep(50);
    } while (true);
}

UserState will be passed to ProgressChanged event args

public void backgroundWorkerXY_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    var args = (Tuple<int, int>)e.UserState;
    pictureBox1.Location = new Point(args.Item1, args.Item2) );
}

Upvotes: 3

Uwe Keim
Uwe Keim

Reputation: 40736

You could pass a custom class, like e.g.

public class MyCustomClass
{
    public int X {get;set;}
    public int Y {get;set;}
}

Then use it similar to this:

public void backgroundWorkerXY_DoWork(object sender, DoWorkEventArgs e)
{
    do
    {
        backgroundWorkerX.ReportProgress(
            0,
            new MyCustomClass 
            {
                X = -(RSSI_PI1_ST1),
                Y = -(RSSI_PI1_ST1) + 5
            } );

        Thread.Sleep(50);
    } while (true);
}

And consume it like:

public void backgroundWorkerXY_ProgressChanged(
    object sender, 
    ProgressChangedEventArgs e)
{
    var my = (MyCustomClass)e.UserState;

    pictureBox1.Location = new Point(my.X, my.Y);
}

Some references:

Upvotes: 1

Related Questions