Home > Software design >  Cannot invoke changes in form a second time
Cannot invoke changes in form a second time

Time:01-13

I try to write an app where I need to use a scanner via COM-port. I'm using an enabled SerialPort object for it, scanning works fine in the main form.

I then use a button to toggle if the main form should be able to do the ReadExisting() method.

private void ScannerDataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
try
{
    SerialPort sp = (SerialPort)sender;
    string indata = sp.ReadExisting();`
    if (string.IsNullOrEmpty(indata))
    {
        return;
    }
    Invoke(new MethodInvoker(delegate { cbValues.SelectedItem = values; }));
}
    catch (Exception ex)
    {
        log.Error($"{ex}");
    }
}

(cbValues is a ComboBox) (System.IO.Ports.SerialPort)

In my mainform I use this to create a new form:

var form = new Form2(_data, scanner);
form.ShowDialog();

Then the form is shown as expected. On the first try when I scan stuff in the new form everything works fine.

Then I close the 'child' form.

Then I reopen it and it is shown and the scanner event is fired.

This is my constructor:

InitializeComponent();
HandleCreated  = new EventHandler((sender, args) =>
{
    scanner.DataReceived  = new SerialDataReceivedEventHandler(ScannerDataReceivedHandler);
});

In my event I try to invoke a change in a combobox.

BeginInvoke(new MethodInvoker(delegate { cbValues.SelectedItem = values; }));

On my second try the form is not created (IsCreated = false) and doesn't have a handle (IsHandleCreated = false), despite being visible AND reacting to the scanner.

I cannot wrap my head around it. I also tried using the form to have it disposed after usage, but it doesn't work.

Does anyone have a guess?

CodePudding user response:

Well I kind of found a solution by try and error...
I inserted the following code at the start of my eventhandler:

if(!IsHandleCreated)
{
    this.BeginInvoke(new MethodInvoker(delegate { CreateHandle(); }));
}

Is there a better solution for it?

CodePudding user response:

I read your post and code carefully. As I understand it, scanner is a member variable of MainForm, and you're passing it as an argument to the Form2 constructor. More than a guess, what I'm seeing is a roundabout way to subscribe to the event that should be attached in the main form one time as soon as the scanner is instantiated.

public partial class MainForm : Form
{
    public MainForm()
    {
        InitializeComponent();
        scanner = new Scanner();
        scanner.DataReceived  = ScannerDataReceivedHandler;
    }
    // F O R    E X A M P L E
    // The class name `Scanner` is just a placeholder for this example.
    // The point is, it's being declared/instantiated "somewhere".
    private readonly Scanner scanner;
    private void ScannerDataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
    {
        // Do something
    }
}
  • Related