Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 让我的QR扫描器工作有很多困难_C#_Wpf_Serial Port - Fatal编程技术网

C# 让我的QR扫描器工作有很多困难

C# 让我的QR扫描器工作有很多困难,c#,wpf,serial-port,C#,Wpf,Serial Port,我似乎无法让我的程序正常工作。。。 我正在开发一个销售点系统,我需要扫描一篇文章,并将其显示在我的WPF C#程序中。 我有工作代码,但奇怪的是,当我连续扫描多次时,我得到两个消息框(调试),而不是一个。我的代码如下: 以下代码初始化了我的Serialport,但没有打开与它的连接: private void Cb1_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (string.IsNullOrEmpt

我似乎无法让我的程序正常工作。。。 我正在开发一个销售点系统,我需要扫描一篇文章,并将其显示在我的WPF C#程序中。 我有工作代码,但奇怪的是,当我连续扫描多次时,我得到两个消息框(调试),而不是一个。我的代码如下: 以下代码初始化了我的Serialport,但没有打开与它的连接:

private void Cb1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (string.IsNullOrEmpty(cb1.SelectedItem.ToString())) { MessageBox.Show("Er is nog niet een selectie gemaakt "); }
    else
    {
        sp = new SerialPort(cb1.SelectedItem.ToString());
        sp.BaudRate = 9600;
        sp.DataBits = 8;
        sp.Parity = Parity.None;
        sp.StopBits = StopBits.One;
        sp.Handshake = Handshake.None;
        disconnect.IsEnabled = true; //Irrelevant
    }
}
我按下了下面的按钮,检查连接是否打开。如果与串行端口的连接未打开,它将连接并添加一个等待数据的事件处理程序:

private void Artikel_Scan(object sender, RoutedEventArgs e)
{
    if(sp != null)
    {
        try
        {
            if (!sp.IsOpen)
            {
                sp.Open();
                sp.DataReceived += new SerialDataReceivedEventHandler(artikel_DataReceived);
            }
            else
                sp.DataReceived += new SerialDataReceivedEventHandler(artikel_DataReceived);
        }
        catch (Exception ex) { MessageBox.Show(ex.Message); }
    }
    else
    {
        MessageBox.Show("Configure the QR Scanner Please.");
    }
}
下面的代码在messagebox中打印接收到的数据:

private void artikel_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    byte[] buffer = new byte[20];
    Action kickoffRead = null;
    kickoffRead = delegate
    {
        sp.BaseStream.BeginRead(buffer, 0, buffer.Length, delegate (IAsyncResult ar)
            {
                try
                {
                    int actualLength = sp.BaseStream.EndRead(ar);
                    byte[] received = new byte[actualLength+1];
                    Buffer.BlockCopy(buffer, 0, received, 0, actualLength);
                    RaiseAppSerialDataEvent(received);
                }
                catch (IO.IOException exc)
                {
                    MessageBox.Show("ERROR == > " + exc.ToString());
                }
                kickoffRead();
            }, null);
    };
    kickoffRead();
}

private void RaiseAppSerialDataEvent(byte[] Data)
{
    string Result = Encoding.Default.GetString(Data);
    MessageBox.Show(Result);
    /*Dispatcher.Invoke(new Action(() =>
    {
        artikeltxt.Text = Result;
    }));*/
}
我使用以下代码关闭端口:

sp.DataReceived -= new SerialDataReceivedEventHandler(artikel_DataReceived);
我有两个二维码,包含以下信息:

  • 5039085修订版-
  • 5034917
第一次扫描第一个二维码时,我只得到一个显示二维码全部内容的消息框。有时,当我扫描第二个二维码时,它也会显示二维码的全部内容。但有时我会收到两个单独的消息框,显示其中一个二维码的部分信息

我有一个Datalogic Quickscan 2430 QR扫描仪,使用USB-COM作为接口进行配置,触发模式为单触发

我能做些什么来解决我的问题?我对串行编程有点陌生,所以我不确定我是否做对了

编辑:在测试各种东西时,我想我弄坏了扫描仪。我的扫描仪一直在重新连接到windows。当我打开设备管理器时,它会很快出现,然后持续消失。希望制造商能修好我的扫描仪

编辑2:我在@Baddack的帮助下解决了我的问题。我将所有串行代码放在一个类中,并调用mainwindow.xaml中的函数。我有一个执行以下功能的按钮:

public void Artikel_Scan(TextBox tb1)
{
    tbartikel = tb1;
    if (!isSerialNull())
    {
        try
        {
            if (!isSerialOpen())
            {
                sp.Open();
                sp.DataReceived += new IO.SerialDataReceivedEventHandler(artikel_DataReceived);
            }
            else
                sp.DataReceived += new IO.SerialDataReceivedEventHandler(artikel_DataReceived);
        }
        catch(Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
}
这是我的DataReceived函数,它使用Dispatcher.BeginInvoke启动另一个函数:

private void artikel_DataReceived(object sender, IO.SerialDataReceivedEventArgs e)
{
    string data = sp.ReadExisting();
    data = data.Replace("\r", string.Empty);
    data = data.Replace("\n", string.Empty);
    data = data.Replace(Environment.NewLine, string.Empty);
    data = IllegalCharacterCheck(data);
    if (!string.IsNullOrEmpty(data))
    {
        string payload = data.Substring(1, data.Length - 1);
        Application.Current.Dispatcher.BeginInvoke(new Action(() => artikelDatareceived(payload)));
    }
}

private void artikelDatareceived(string payload)
{
    tbartikel.Text = payload;
}
文本框中填充文本后,将调用TextChanged事件,关闭我的serialport连接并对其进行处理:

public void artikel_Close()
{
    sp.DataReceived -= new IO.SerialDataReceivedEventHandler(artikel_DataReceived);
    sp.Close();
    sp.Dispose();
}

我已经对它进行了测试,现在它工作得很好。

您没有更新上面的代码,所以我不确定您到底更改了什么。但我认为关键是您只能调用
sp.DataReceived+=newserialdatareceivedeventhandler(artikel\u DataReceived)一次,否则它将多次订阅该事件

做一个简单的测试,创建一个包含两个按钮和一个文本框的表单。使用下面的代码,按下打开按钮,进行一些扫描,然后关闭它。让我知道结果

SerialPort sp;

private void buttonOpen_Click(object sender, EventArgs e)
{
    if (sp != null)
        return;

    if (string.IsNullOrEmpty(cb1.SelectedItem.ToString())) 
    {
        MessageBox.Show("Er is nog niet een selectie gemaakt ");
        return;
    }

    sp = new SerialPort();
    sp.PortName = "COM1";   //put your comport # here
    sp.BaudRate = 9600;
    sp.DataBits = 8;
    sp.Parity = Parity.None;
    sp.StopBits = StopBits.One;
    sp.Handshake = Handshake.None;
    sp.DataReceived += new SerialDataReceivedEventHandler(artikel_DataReceived);

    sp.Open();
}

private void buttonClose_Click(object sender, EventArgs e)
{
    sp.DataReceived -= new SerialDataReceivedEventHandler(artikel_DataReceived);
    sp.Close();
    sp.Dispose();
}

private void artikel_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    string Data = sp.ReadExisting();

    this.Invoke((MethodInvoker)delegate
    {
        textBox1.Text += Data;
    });
}

我认为每次扫描时都会创建多个
DataReceived
事件,这就是为什么再次扫描时会多次触发该事件的原因。将事件的创建放在某个地方,它只会被调用一次,将它放在扫描方法中会导致问题。我已将serial.Open()添加到初始化代码中(我的答案中的第一个代码示例),再次尝试,结果仍然发生。我还向DataReceived函数添加了最后一个代码示例。接收数据后,它关闭datahandler。它没有解决我的问题。当我扫描代码5034917几次时,有时会出现两个消息框。第一个消息框包含“5”,而第二个消息框包含“034917”。如果在POS应用程序中使用扫描仪,最好使用统一POS API,而不是直接使用COM端口。规范在这里,设备驱动程序将在这里可用。我创建了一个新项目,必须编辑
this.Invoke((MethodInvoker)delegate{textBox1.Text+=Data;})
Dispatcher.BeginInvoke(新操作(委托{scan.Text=Data;}))。然而,当我尝试测试它时,我的扫描仪坏了。我刚把它送到制造商那里去修理。我的扫描仪已经修好了,我把它设置成接口USB-COM,然后试着一个接一个地扫描我的两个二维码,结果是:,奇怪的是,我得到了一个奇怪的“y”字。它和你描述的不完全一样,但是关闭和处理serialport连接是解决问题的关键。我已经更新了代码,我将接受此解决方案。