1

I want to change the text in a textbox of a Windows Form with different error messages. These error messages are set to an output string using the same method, but i can't pass the string as a parameter.

Here's how i call a new backgroundworker to safely change the text in the textbox:

worker.DoWork += worker_DoWork;
worker.RunWorkerAsync(argument: error));

Then i try to invoke the call:

private void worker_DoWork(object sender, DoWorkEventArgs e)
    {

        string output = e.Argument.ToString();
        object[] par = new object[] { output };


        Delegate del = new DELEGATE(changeErrortext);

        this.Invoke(del,par);

    }

    private void changeErrorText()
    {

        textBoxError.Text = output.ToString();
    }

I think i've got to assign the output in the object to the one in the changeErrorText, but i don't really know how to do it.

I've tried different methods, but none have worked. I'm new to C#, so tell me if and where i've messed up.

Iliass Nassibane
  • 651
  • 7
  • 15
  • Have you tried to add parameter to `changeErrorText`? like `private void changeErrorText(string output)`? – Guru Stron May 07 '20 at 17:13
  • Do you have output variable declared in the class? Because you are using ` textBoxError.Text = output.ToString();` and output is not declared in the method parameters – Piotr May 07 '20 at 17:24
  • -Guru Stron, yes, i've tried it but i forgot to mention it. if i add the parameter there's and arror on "Delegate del = new DELEGATE(changeErrortext);" becouse the parameter is not mentioned. And if add it on this as well, the error changes in "method name expected". -Pior. if i declare it in the class there are no compilation errors but nothing happens (the debugger console return this: "exeption generated: 'System.Reflection.TargetParameterCountException' in System.Windows.Forms.dll") – thegavereguy May 07 '20 at 19:10

1 Answers1

0

Instantiate the necessary event handlers

Place eventhandlers in the constructor of the form. For example:

public Form1()
{
    InitializeComponent(); // Standard initialization component method...

    backgroundWorker1.DoWork += backgroundWorker1_DoWork;
    backgroundWorker1.RunWorkerCompleted += backgroundWorker1_RunWorkerCompleted;
}

Using the DoWork AND the RunWorkerCompleted events

The way you used 'worker.DoWork += worker_DoWork;' should be expanded with the "RunWorkerCompleted" event. The DoWork event for the operation and the RunWorkerCompleted to handle the completed operation. This event is also usefull when you want to use cancellation or exception handling. This also gets called automatically, so there is no need for a dedicated "changeErrorText"-method. Example code:

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
   label1.Text = e.Result.ToString();
}

You don't have to use a Delegate to pass parameters

The parameters can be passed the way you wrote the RunWorkAsync. The only thing you might want to do is placing that method in a (click) event. For example:

private void button1_Click(object sender, EventArgs e)
{
   int value = 123; // example input
   backgroundWorker1.RunWorkerAsync(argument: value);
}

The full code doc:

public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            backgroundWorker1.DoWork += backgroundWorker1_DoWork;
            backgroundWorker1.RunWorkerCompleted += backgroundWorker1_RunWorkerCompleted;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            int value = 123;
            backgroundWorker1.RunWorkerAsync(argument: value);
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            string output = e.Argument.ToString();

            e.Result = output;
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            label1.Text = e.Result.ToString();
        }
    }

I hope i've helped you with the above explanations.

Sources

  1. Sending Arguments To Background Worker?;
  2. https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.backgroundworker?view=netcore-3.1
Iliass Nassibane
  • 651
  • 7
  • 15
  • thank you for your answer. I've tried your solution and it still somehow result in an error where the text in the textbox is changed. I've tried other solutions like the one explained in the second source link that you provided and the one i've found here (https://www.codeproject.com/Articles/99143/BackgroundWorker-Class-Sample-for-Beginners), but both are refering to a change in a progressbar and i don't really know how to adapt those for my code – thegavereguy May 10 '20 at 15:44
  • @thegavereguy in fact the 'int value' in the button_click event can be seen as a provider to change the textbox. Say for instance one of those error messages you want to display or change to. You could code additional logic to provide the events with context to change to. For example: 'string value = provideErrorMessage(textbox.text)'. – Iliass Nassibane May 10 '20 at 15:56