C# 移动扫描仪值表现得很奇怪

标签 c# delegates windows-mobile barcode-scanner

因此,我编写了一个快速示例程序来更好地理解 Janam 扫描枪,但是我遇到了我从未见过的问题,尽管我认为可能是由于位于不同的线程上并在它们之间传递值而引起的。所以我不相信我正确使用了委托(delegate)。如有帮助,我们将不胜感激。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Scanner;

namespace ScannerTest
{
public partial class Form1 : Form
{
    //Delegates
    private delegate void RefreshValuesDelegate();
    private delegate void AddScannedItemDelegate(Item item);
    // SINGLETON //////////////////////////////////////
    private static Form1 instance = null;

    public static Form1 GetInstance()
    {
        if (instance == null)
            instance = new Form1();

        return instance;
    }
    ///////////////////////////////////////////////////

    public Form1()
    {
        InitializeComponent();
    }
    void Form1_Load(object sender, EventArgs e)
    {
        /**************/
        //SCANNER ACTIVATE                       

        GlobalScanner.GetInstance().Close();
        GlobalScanner.GetInstance().BarcodeDelegateDirector = new GlobalScanner.BarcodeDelegate(Form1.GetInstance().processScannedBarcode);
        GlobalScanner.GetInstance().Open();
        /**************/

    }
    // Add the new part unless the part number contains 
    // spaces. In that case cancel the add. 
    private void button1_Click(object sender, EventArgs e)
    {
        if (textBox1.Text.Equals("") || textBox2.Text.Equals(""))
        {
            MessageBox.Show("item names or barcodes cannot be blank.");
        }
        else
        {
            Item temp = new Item(textBox1.Text, textBox2.Text, DateTime.Now);
            if (temp.ItemCheck == true)
            {
                AddToList(temp);
            }
        }
    }
    public void processScannedBarcode(string scannedBarcode)
    {
        if (scannedBarcode != null && scannedBarcode.Length > 0) // 0 = SUCCESS Symbol.Results.SUCCESS
        {
            Item temp = new Item();
            temp.ItemName = "N/A";
            temp.BarcodeNumber = scannedBarcode;
            String tempDate = DateTime.Now.ToShortDateString();
            String tempTime = DateTime.Now.ToShortTimeString();
            temp.ScanDate = tempDate + tempTime;
            AddScannedItem(temp);
        }
    }
    private void AddScannedItem(Item item)
    {
        if (this.InvokeRequired == true)
        {
            this.Invoke(new AddScannedItemDelegate(AddScannedItem), new object[] { item });
        }
        else
        {
            this.textBox2.Text = item.BarcodeNumber;
            this.textBox1.Text = item.ItemName; // description not available
            item.ScanDate = DateTime.Now.ToLongDateString();
            //DateTime readDate = DateTime.Now;
            //cargo.SetReadDate(readDate);
            RefreshValues();
            AddToList(item);
        }
    }
    private void AddToList(Item item)
    {
        string tempItem = item.ItemName;
        string tempBarcode = item.BarcodeNumber;
        string tempDate = item.ScanDate;
        ListViewItem newRow = new ListViewItem(tempItem);
        newRow.SubItems.Add(tempBarcode);
        newRow.SubItems.Add(tempDate);
        listView1.Items.Add(newRow);
        RefreshValues();
        //MessageBox.Show(string.Format("TextBox1: {0} TextBox2: {1}", tempItem, tempBarcode));
        textBox2.Text = "";
        textBox1.Text = "";
    }
    public void RefreshValues()
    {
        if (this.InvokeRequired == true)
        {
            this.Invoke(new RefreshValuesDelegate(RefreshValues));
        }
        else
        {
            listView1.Refresh();
        }
    }
}

// A simple business object for example purposes. 
public class Item
{
    private string name;
    private string number;
    private string date;
    private bool check = true;

    public Item() { }
    public Item(string nameForItem, string numberForBarcode, DateTime scandate)
    {
        ItemName = nameForItem;
        BarcodeNumber = numberForBarcode;
        date = scandate.ToShortDateString();
    }

    public string ItemName
    {
        get 
        { 
            return name; 
        }
        set 
        {
            if (value.Length <= 45)
            {
                name = value;
            }
            else
            {
                MessageBox.Show("Item name to long. Must be less than 45 characters.");
                ItemCheck = false;
            }
        }
    }

    public string BarcodeNumber
    {
        get 
        { 
            return number; 
        }
        set 
        {
            if (value.Length <= 20)
            {
                number = value; 
            }
            else
            {
                MessageBox.Show("Barcode is to long. Must be less than 20 digits.");
                ItemCheck = false;
            }
        }
    }
    public string ScanDate
    {
        get
        {
            return date;
        }
        set
        {
            date = value;
        }
    }

    public bool ItemCheck
    {
        get
        {
            return check;
        }
        set
        {
            check = value;
        }
    }
}
}

因此,手动输入值可以正常工作,但是当扫描仪被激活并读取值时。当代码遍历列表时,调试器会显示设置和存储的正确值,但屏幕不会显示扫描仪中的任何内容,并且不会像手动键入时那样将值保存到 ListView 中。

就像我之前所说的,我相信这是委托(delegate)和扫描仪线程将值传递给它不喜欢的主线程的问题。

感谢您提前提供的帮助。

这是手动输入值的 View manual typing

这是正在使用的扫描仪的 View 。我取消了消息框的注释,这样你就可以看到它正在拾取一些东西。 scanner

回答某人的问题: enter image description here

这里是全局扫描仪,供那些想要查看的人使用。

using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;

namespace Scanner
{
public class GlobalScanner
{
    #region About using the delegate in this class
    /*  We are actually using one central class to do the scanning, but user can scan from different screens.
      * If we don't have a delegate we will have the following scenario. We scan the barcode, the barcode will be 
      * captured in our scanner implementation class "For example: IntermecBarcodeScanner" and we will have no way to return
      * the barcode back to the scanning screen. The delegate will actually help us to do that job. The delegate will
      * be associated with a method inside the scanning form. It will carry the scanned barcode over to that method
      * inside the scanning form.
      * 
      * We need 3 main things to get the delegate working:
      * 1- Declare a delegate variable
           public delegate void BarcodeDelegate(string barcode);
      * 2- Initialize a delegate and associate it with the appropropriate method in the scanning form: 
      *     Example: GlobalScanner.GetInstance().BarcodeDelegateDirector = new GlobalScanner.BarcodeDelegate(this.ScanBarcodeEvent);
      *     We need the above line of code to be in the scanning form. That's how we associate the ScanBarcodeEvent() method
      *     with the delegate that is in the GlobalScanner class.
      * 3- In GlobalScanner class we created two variables to help us to connect to the scanner implementation class such as
      *    the IntermecBarcodeScanner. Those two variables are: barcodeDelegateInstance and barcodeData
      */
    #endregion

    //Declare a delegate
    public delegate void BarcodeDelegate(string barcode);

    private IBarcodeScanner scanner = null;

    // SINGLETON //////////////////////////////////////
    private static GlobalScanner instance = null;

    public static GlobalScanner GetInstance()
    {
        if (instance == null)
        {
            instance = new GlobalScanner();
        }

        return instance;
    }
    // ////////////////////////////////////////////////


    private BarcodeDelegate barcodeDelegateInstance = null;
    //BarcodeDelegateDirector will be accessed to associate the method 
    //that's in the scanning form with the delegate
    public  BarcodeDelegate BarcodeDelegateDirector
    {
        get { return barcodeDelegateInstance; }
        set { barcodeDelegateInstance = value; }
    }

    //We also created this variable to set the barcode value from other classes such as IntermecBarcodeScanner
    private string barcodeData;
    public string BarcodeData
    {
        get { return barcodeData; }
        set
        {
            barcodeData = value;
            barcodeDelegateInstance(barcodeData); //barcodeData is the scanned barcode and it comes from the GlobalScanner implementation
        }
    }

    public void Open()
    {
        String deviceName = Platform.GetOEMInfo();
        if (deviceName != null)
        {                
            if (scanner == null)
            {
                if (deviceName.Equals(Global.INTERMEC_DEVICE_1) || deviceName.Equals(Global.INTERMEC_DEVICE_2) || deviceName.Equals(Global.INTERMEC_DEVICE_3))
                    scanner = new IntermecBarcodeScanner();
                else if (deviceName.Equals(Global.JANAM_DEVICE_1) || deviceName.Equals(Global.JANAM_DEVICE_2) || deviceName.Equals(Global.JANAM_DEVICE_3))
                    scanner = new JanamXMBarcodeScanner();
                else if (deviceName.Equals(Global.JANAM_XG_DEVICE_1) || deviceName.Equals(Global.JANAM_XG_DEVICE_2) || deviceName.Equals(Global.JANAM_XG_DEVICE_3))
                    scanner = new JanamXGBarcodeScanner();
                else if (deviceName.Equals(Global.MOTOROLA_DEVICE_1) || deviceName.Equals(Global.MOTOROLA_DEVICE_2) || deviceName.Equals(Global.MOTOROLA_DEVICE_3))
                    scanner = new MotorolaBarcodeScanner();

            }

            scanner.Open();
        }
    }

    public void Close()
    {
        if (scanner != null)
        {
            scanner.Close();
        }

    }
}
}

最佳答案

如果您认为这是线程间问题,您可以使用锁对象来确保只有单个线程可以访问事件数据:

全局 对象lockObject = new object(); 必须定义并在 AddToList 中将所有代码包围 锁(锁对象) { } 上述确保一次只有一个 AddToList 正在运行。

我使用条形码扫描仪向委托(delegate)人看到的另一个差异是委托(delegate)用法:在我的代码中,我首先声明委托(delegate)的新变量,然后调用该变量上的调用。但这不应该对功能产生影响。

关于C# 移动扫描仪值表现得很奇怪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18082747/

相关文章:

c++ - 使用 winsock 从多个主机接收多个数据报

c# - 位运算符如何与枚举一起使用

c# - 使用字符串动态创建 (LLBLGen) Linq 查询

c# - WPF UserControl Dependency Property Setter 未触发

iPhone SDK : Delegate method not getting called-Troubleshooting

c# - Windows CE 4.2 的限制是什么?

c# - Silverlight 导航 + 参数?

ios - 如何将委托(delegate)传递的数据转换为不同的值?

c# - 如何使用 NUnit 测试回调

.net - 如何在.NET CF中以编程方式打开/关闭蓝牙?