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
}
}