Search code examples
c#delegateswindows-mobilebarcode-scanner

C# mobile scanner values acting weird


So I wrote a quick example program to better understand the Janam scanner gun however I am running into problems that I have never seen though I believe may be caused due to being on different threads and passing values between them. So I do not believe I am correctly using delegates. and help would be appreciated.

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

So manually typing out the values works properly but when the scanner is activated and reads in a value. The debugger shows the proper values getting set and stored as the code goes through the list however the screen shows nothing from the scanner and does not save the value to the listview as it does when manually typed.

Like I said before I believe its a problem with delegates and the scanner thread passing the value to the main thread that it just doesn't like.

Thanks for the help in advance.

Here is a view of manually typing in values manual typing

Here is a view of scanner being used. I un-commented the messagebox so you could see it is picking up something. scanner

Answer to someones question: enter image description here

Here is the global scanner for those that would like to check it out.

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();
        }

    }
}
}

Solution

  • So I finally figured out how to resolve my problem although I do not fully understand why this fixes my problem and only stumbled upon it when I was setting all my textbox1.text to form1.GetInstance().textbox1.text which started making my manual input act the same way my scan inputs were. This lead me to believe that my form1.instance was having issues setting the items on my form. For future answer seekers to this same problem, I fixed my code with the following change. From this

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

    To this

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

    Simply removing the Form1.GetInstance() resolved this issue however there is only one instance so there should really not be a difference. If anyone can explain this for me and future answer seekers, we would appreciate it very much.