简体   繁体   English

无法第二次调用表单中的更改

[英]Cannot invoke changes in form a second time

I try to write an app where I need to use a scanner via COM-port.我尝试编写一个应用程序,我需要通过 COM 端口使用扫描仪。 I'm using an enabled SerialPort object for it, scanning works fine in the main form.我为此使用了启用的 SerialPort object,在主窗体中扫描工作正常。

I then use a button to toggle if the main form should be able to do the ReadExisting() method.然后我使用一个按钮来切换主窗体是否应该能够执行ReadExisting()方法。

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) (cbValues 是一个 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.在我的事件中,我尝试调用 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.在我的第二次尝试中,表单未创建 (IsCreated = false) 并且没有句柄 (IsHandleCreated = false),尽管它是可见的并且对扫描仪有反应。

I cannot wrap my head around it.我无法绕过它。 I also tried using the form to have it disposed after usage, but it doesn't work.我也尝试using表单在使用后将其处理掉,但它不起作用。

Does anyone have a guess?有人猜到了吗?

I solved it.我解决了。
It is ugly, but it works.它很丑陋,但它有效。
I hope there will be a future me with a nice solution.我希望未来的我会有一个很好的解决方案。
The solution: closing the SerialPort object via scanner.Close() and opening it in the other form.解决办法:通过scanner.Close scanner.Close()关闭SerialPort object,用另一种形式打开。
After everything is scanned closing that object on Form2_FormClosing(object sender, FormClosingEventArgs e) .扫描完所有内容后,关闭Form2_FormClosing(object sender, FormClosingEventArgs e)上的 object。

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.据我了解, scannerMainForm的成员变量,您将其作为参数传递给Form2构造函数。 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.不仅仅是猜测,我所看到的是一种迂回的方式来订阅应该scanner实例化后立即附加到主窗体中的事件。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM