Xamarin.Forms icon indicating copy to clipboard operation
Xamarin.Forms copied to clipboard

[Bug] Barcode Scanner triggers carriage return before reading all values

Open NicolaZuc opened this issue 3 years ago • 27 comments

Hi, i've discovered a strange behavior when using USB scanners in keyboard emulation mode with carriage returnon UWP. When i try to scan a value while i have focus on a control with a text input and a "completed" event, the completed event is triggered before that the scanner has read the other values.

To reproduce the problem:

  1. put focus on an entry
  2. scan a value from usb scanner in keyboard emulation mode

Expected Behavior

ReturnCommand triggered ReturnCommandParameter with value as entry.text = scanned barcode

Actual Behavior

ReturnCommand triggered ReturnCommandParameter with value as empty

Basic Information

However if i don't use ReturnCommandParameter and instead use a string binded in my view model and wait some time, the value then is correct. Example:

//xaml
<Entry Text={Binding EntryText}/>

//View model
private async void OnReturn(){ // in this situation the value is null
    if (string.IsNullOrEmpty(EntryText))
        Console.WriteLine("Error!")
}

private async void OnReturn(){ // in this situation the value is not null
    await Task.Delay(500);
    if (string.IsNullOrEmpty(EntryText))
        Console.WriteLine("Error!")
}

I've found similar problems here, here and here

NicolaZuc avatar Dec 22 '21 11:12 NicolaZuc

Hey, thanks for the report! From what you're saying I think you might have a wrong understanding of ReturnCommandParameter. This property is something that serves as input. You can specify a value here that can be used inside of the command that you specify with ReturnCommand.

You should indeed get the value from the property that you are binding to in your view model. You might be confused with how events work. They indeed do have arguments that typically have informations about the event that just happened. That is not the case for commands.

Hope this helps!

jfversluis avatar Dec 22 '21 13:12 jfversluis

You didn't understand my report. I know that returncommandparameter is used as an input, what i'm saying is that it is empty when i use it with a scanner! ReturnCommandParameter={Binding Source={x:Reference Entry}, Path=Text} If i write in my entry writing the text then the returncommandparameter has the correct value, else it is empty.

NicolaZuc avatar Dec 23 '21 08:12 NicolaZuc

But still, how do you expect this to work? The text of that entry only gets filled when the return command is fired, so how is it supposed to act as an input at the same time? I'm probably not understanding what you are trying to do indeed, but to be honest it seems like me that you would want to solve this another way and this is not really a bug in our codebase.

jfversluis avatar Dec 23 '21 09:12 jfversluis

if i write: "hello world" in my entry and then press enter, my returncommandparameter contains hello world. If i scan "hello world" with my scanner without carriage return then the entry contains hello world and then i press manually enter, my returncommandparameter contains hello world. If i scan "hello world" with my scanner with carriage return then the entry contains hello world and automatically press enter, my returncommandparameter contains empty. This doesn't seem a bug to you? Or did i not explain it correctly? If i can explain it better or u can explain me better where am i wrong in what i'm saying it would help me to understand, unfortunately my english is not so good so i'm trying to do my best. Thanks for your time

NicolaZuc avatar Dec 23 '21 09:12 NicolaZuc

Can you please re-open the issue?

NicolaZuc avatar Dec 24 '21 20:12 NicolaZuc

If you can provide me with a runnable reproduction of this problem in a GitHub repository that I can take a look at I think that might help clear things up.

jfversluis avatar Dec 27 '21 12:12 jfversluis

i can give u a repro, but do u have an usb barcode scanner to test? Else u will never be able to detect the problem.

NicolaZuc avatar Dec 27 '21 21:12 NicolaZuc

I do not, that is also part of the problem indeed :) But with a repro I might be able to poke around and see if I can detect where things might go wrong

jfversluis avatar Dec 30 '21 08:12 jfversluis

Ok, i'll give you a repro the 10th of january, at the moment i'm on vacation and i don't have my equipment with me. Do you want also a video to show you the problem?

NicolaZuc avatar Dec 30 '21 08:12 NicolaZuc

If you would be able to do that that would be awesome :)

jfversluis avatar Dec 30 '21 08:12 jfversluis

Hi, i will give you a repro as soon as i can, atm there are some pandemic problems and i can't go to the office.

NicolaZuc avatar Jan 17 '22 16:01 NicolaZuc

Sorry to hear that @NicolaZuc stay safe!

jfversluis avatar Jan 18 '22 08:01 jfversluis

Hi and sorry for the delay. Here is an example of runnable code that will show you the problem and a video running with the barcode scanner. As you can see in the video, the value that is being read is empty in all cases except for the last one (binding value on text property of the entry and waiting 500ms). I've also used the barcode scanner in the notedpad to show how it works and which characters it use (read characters + return). If there is something else that i can give to you to let you better understand my problem just say it and i'll do my best.

Greetings, Nicola

repro.zip

NicolaZuc avatar Feb 08 '22 12:02 NicolaZuc

Any news on this?

NicolaZuc avatar Mar 08 '22 08:03 NicolaZuc

Hi NicolaZuc can you resolve the issue? I got exactly the same problem as you. When i use the barcode scanner with the application i´m developing in Android or IOS there is no problem, but when i use it with UWP it sends an enter before it writes the content of the scanned code

BoingDeFresa avatar Mar 31 '22 19:03 BoingDeFresa

Hi NicolaZuc can you resolve the issue? I got exactly the same problem as you. When i use the barcode scanner with the application i´m developing in Android or IOS there is no problem, but when i use it with UWP it sends an enter before it writes the content of the scanned code

Unfortunately no, i'm waiting that @jfversluis updates me on this matter

NicolaZuc avatar Apr 01 '22 14:04 NicolaZuc

Can i have an update on this matter please?

NicolaZuc avatar May 23 '22 08:05 NicolaZuc

No updates to share unfortunately

jfversluis avatar May 23 '22 09:05 jfversluis

Hi,

I've the same issue on Xamarin Forms after updated from 5.0.0.2012 to 5.0.0.2478. @NicolaZuc, you have any solution? I think is due to Xamarin.Google.Android.Material.

SimLeongChun avatar Jul 23 '22 13:07 SimLeongChun

Hi NicolaZuc,

I managed to solved it by removing Entry.Text = "" in OnFocus EventHandler. You may try it.

SimLeongChun avatar Jul 23 '22 13:07 SimLeongChun

Hi NicolaZuc,

I managed to solved it by removing Entry.Text = "" in OnFocus EventHandler. You may try it.

Hi, that's something that u have on ur code because u wrote it, it can't work for me. Thanks anyway ;)

NicolaZuc avatar Jul 24 '22 14:07 NicolaZuc

@SimLeongChun I am also had issues when upgrading to 5.0.0.2478. We dont use any entry, we just catch key on OnKeyDown in MainActivity. Now it never returns new line symbol (end of barcode). Maybe do you have suggestions?

valentasm1 avatar Aug 24 '22 11:08 valentasm1

@SimLeongChun I am also had issues when upgrading to 5.0.0.2478. We dont use any entry, we just catch key on OnKeyDown in MainActivity. Now it never returns new line symbol (end of barcode). Maybe do you have suggestions?

I'm not sure on this since my issue is from barcode reader. But, you can try append "\n" or "\r\n" explicitly to add new line in your OnKeyDown Event.

SimLeongChun avatar Aug 24 '22 11:08 SimLeongChun

@SimLeongChun Barcode reader acts as keybourd and send barcode as char and when it end reads it sends new line char "\n". That new line is never trigered in event. Everything was fine before 5.0.0.2478. I am not focuses entry. Like no focus at all

valentasm1 avatar Aug 24 '22 11:08 valentasm1

@SimLeongChun Barcode reader acts as keybourd and send barcode as char and when it end reads it sends new line char "\n". That new line is never trigered in event. Everything was fine before 5.0.0.2478. I am not focuses entry. Like no focus at all

For my case, I had a OnFocused EventHandler with myEntry.Text = "", and this cause the issue. I solved it by comment out this line. Maybe you can try add OnFocus EventHandler. But I do add Task.Run(async () => {await Task.Delay(600); myEntry.Focus()});

You can refer to this link as reference: https://stackoverflow.com/questions/38240733/why-entrys-focus-method-isnt-working-from-pages-constructor

SimLeongChun avatar Aug 24 '22 12:08 SimLeongChun

I'm having the same issue. The barcode scanner acts as a keyboard wedge, and it sends a CRLF at the end of the scan. Sometimes it works properly, but it usually cuts a few characters off. When the completed event handler detects the CRLF, I use the EventToCommandBehavior to fire a command and pass a reference to the entry, but it's like the entry box didn't finish receiving the text when it detected the CRLF. Let's say you are scanning a barcode that represents 123456, it may only read 123 in the entry box. On the barcode scanner, I can turn off the terminating characters, then manually hit the enter key, and everything works fine. If there was some way to introduce a delay between when the event handler is triggered and the command is called, this would probably resolve the issue.

Here is what my XAML looks like for the entry:

<Entry 
    x:Name="ScanEntry"
    Text="{Binding ScanBoxText,Mode=TwoWay}"
    WidthRequest="350" 
    Placeholder="{Binding ScanBoxPlaceHolder}"
    >

    <Entry.Behaviors>
        <xct:EventToCommandBehavior 
        EventName="Completed" 
        Command="{Binding ScanBoxCompletedCommand}" 
        CommandParameter="{x:Reference ScanEntry}"/>
    </Entry.Behaviors>
    
    <Entry.Effects>
        <xct:LifecycleEffect Loaded="LifeCycleEffect_Loaded" />
    </Entry.Effects>
</Entry>

jkarnopp avatar Aug 25 '22 01:08 jkarnopp

I'm having the same issue. The barcode scanner acts as a keyboard wedge, and it sends a CRLF at the end of the scan. Sometimes it works properly, but it usually cuts a few characters off. When the completed event handler detects the CRLF, I use the EventToCommandBehavior to fire a command and pass a reference to the entry, but it's like the entry box didn't finish receiving the text when it detected the CRLF. Let's say you are scanning a barcode that represents 123456, it may only read 123 in the entry box. On the barcode scanner, I can turn off the terminating characters, then manually hit the enter key, and everything works fine. If there was some way to introduce a delay between when the event handler is triggered and the command is called, this would probably resolve the issue.

Here is what my XAML looks like for the entry:

<Entry 
    x:Name="ScanEntry"
    Text="{Binding ScanBoxText,Mode=TwoWay}"
    WidthRequest="350" 
    Placeholder="{Binding ScanBoxPlaceHolder}"
    >

    <Entry.Behaviors>
        <xct:EventToCommandBehavior 
        EventName="Completed" 
        Command="{Binding ScanBoxCompletedCommand}" 
        CommandParameter="{x:Reference ScanEntry}"/>
    </Entry.Behaviors>
    
    <Entry.Effects>
        <xct:LifecycleEffect Loaded="LifeCycleEffect_Loaded" />
    </Entry.Effects>
</Entry>

Yeah that's exactly what i've reported, the only difference with me is that i've used the EntryReturnCommand instead of using a behavior on the completed event but the final purpose it's the same.

NicolaZuc avatar Aug 25 '22 16:08 NicolaZuc