2013-08-06 34 views
2

因此,我写了一个快速的示例程序,以更好地了解Janam扫描枪,但我遇到的问题,我从来没有见过,虽然我相信可能是由于在不同的线程和传递值之间他们。所以我不相信我正确使用委托。和帮助,将不胜感激。C#移动扫描仪值奇怪

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

因此,手动输入数值可正常工作,但扫描仪被激活并读入数值。调试器会显示正确的值,并在代码通过列表时进行设置和存储,但是屏幕不会显示任何内容,也不会像手动输入时那样将值保存到列表视图中。

就像我之前说过的,我认为它是一个代理和扫描程序线程将值传递给主线程的问题,它只是不喜欢。

感谢您的帮助提前。

以下为手动键入在视图值 manual typing

这里是正在使用扫描仪的图。我没有评论该消息框,所以你可以看到它正在收拾东西。 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(); 
     } 

    } 
} 
} 
+0

这也使用在移动窗口视觉工作室2008年5.0 –

+0

你知道同步原语?Mutex,WaitHandles等?如果你有竞争条件,你必须保护两个线程可以同时处理数据的区域 请参阅'System.Threading'-命名空间。 除此之外,你能告诉可能会出现竞争条件的部分? –

+0

不,我目前不知道关于synchronization0primitives或mutex的信息,但是我明白你的意思,我相信我的AddToList函数是他们可以访问的唯一地方bly重叠但我不确定。 –

回答

1

因此,我终于想出了如何解决我的问题,虽然我不完全明白为什么这解决了我的问题,只有当我将所有textbox1.text设置为form1.GetInstance()。textbox1.text开始使我的手动输入与我的扫描输入一样。这导致我相信我的form1.instance在设置我的表单上的项目时遇到了问题。对于未来回答这个问题的回答者,我修改了以下更改的代码。 从这个

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

对此

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

只需去除Form1.GetInstance()但是解决这个问题只有一个实例所以其实它不应该有差别。如果任何人都可以为我和未来的回答者解释这一点,我们将非常感激。

+0

问题是您确实在GetInstance()函数外分配了实例。尝试添加一行实例= this; InitializeComponents(); – josef

1

如果您的设备的扫描仪设置为将回车附加到扫描结尾,那么您的文本框可能会消隐该行。

例如,如果您向文本框中写入“Hello World!\ n”,会发生什么情况?

UPDATE:

查找设置来配置设备的扫描选项(称为解码下图)。

Settings

这是我的Datalogic猎鹰,但你的XM66应该是这个样子:

XM66Settings

从那里,你可能需要调整扫描仪设置。

ScannerSettings

同样,你的XM66会有所不同,例如:

XM66ScanWedge

+0

没有什么,只是添加该行。看最后一张照片。 –

+0

它是什么类型的设备(制造商和型号)? – jp2code

+0

Janam XM66W http://www.janam.com/xm66-handheld.php –

1

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

a global object lockObject = new object(); 必须被定义并且在AddToList中包含 lock(lockObject) { } 的所有代码以上确保一次只有一个AddToList正在运行。

我看到我的代表与条形码扫描仪的其他差异是委托用法:在我的代码中,我首先声明一个新的委托变量,然后调用var的调用。但这不应该在功能上有所作为。

+0

那么这就是我的想法,但整个功能:if(this.InvokeRequired == true) { this.Invoke(new AddScannedItemDelegate(AddScannedItem),new object [] {item}); } else {是要检查这个问题。 InvokeRequired检查从另一个线程调用它是否正确? –

+0

正确。但是LockObject会确保被调用的函数在任何时候只被调用一次。 – josef

+0

GlobalScanner类的外观如何。这是扫描数据首先被传送的地方。 – josef

1

问题是每次调用GetInstance()时,实例都为空。的GetInstance()创建一个新的Form1的递归(只是使用的调试和阶梯直通下面的代码实例之前=这一点;加入:

using System; 
using System.Linq; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Text; 
using System.Windows.Forms; 

namespace FormInstance 
{ 
    public partial class Form1 : Form 
    { 
     private static Form1 instance = null; 

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

      return instance; 
     } 

     public Form1() 
     { 
      InitializeComponent(); 
      // doTest(); //results in a recursive call! 
      ///without the following instance will never be different than null, as GetInstance creates new Form on every call! 
      instance = this;  
     } 
     void doTest() 
     { 
      Form f1 = this; 
      Form f2 = Form1.GetInstance(); 
      System.Diagnostics.Debug.WriteLine("f1=" + f2.GetType().FullName); 
      System.Diagnostics.Debug.WriteLine("f2=" + f2.GetType().FullName); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      doTest(); //does also not return the current form! 
     } 
    } 
} 
+0

谢谢您的帮助先生。我今天学到了新东西=)。不会再犯这个错误。 –