Home > Mobile >  WPF: How to autoreset/autorefresh the textbox after scanning barcode in WPF?
WPF: How to autoreset/autorefresh the textbox after scanning barcode in WPF?

Time:01-31

I'm making a simple WPF program where the user will basically only need to scan the barcode using a USB barcode scanner and the program will send the data straight to the cloud ERP. Right now, the program works, but the user has to manually click the textbox after scanning, clear the data and scan again. I just want the user to open the software and just keep on scanning using his barcode reader without having to manually erase the textbox data. How can I do that?

<Window x:Class="ProductionScanner.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:viewModel="clr-namespace:ProductionScanner.MVVM.ViewModel"
    xmlns:local="clr-namespace:ProductionScanner"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800"
    Background="#181735" >

<Window.DataContext>
    <viewModel:ReceiptViewModel />
</Window.DataContext>

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="25" />
        <RowDefinition/>
    </Grid.RowDefinitions>

    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>

    <Grid Background="#0F0F2D"
          Grid.ColumnSpan="2">

        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
         
        </Grid.ColumnDefinitions>

        <TextBlock Text="Foods"
                   Foreground="White"
                   Grid.Column="1"
                   VerticalAlignment="Center"
                   HorizontalAlignment="Left"
                   />
        <TextBlock Text="Records"
                   Foreground="White"
                   Grid.Column="2"
                   VerticalAlignment="Center"
                   HorizontalAlignment="Center"
                   />
    </Grid>

    <StackPanel FocusManager.FocusedElement="{Binding ElementName=txtIniFocus}">

        <TextBox x:Name="txtIniFocus" Margin="6" Text="{Binding Barcode, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center" TextWrapping="Wrap" VerticalAlignment="Top" Width="150" Grid.Row="1" TextChanged="TextBox_TextChanged">
            <TextBox.InputBindings>
                <KeyBinding Key="Enter" Command="{Binding ReceiptCommand}" />
            </TextBox.InputBindings>
        </TextBox>

    </StackPanel>

</Grid>

And, the ReceiptViewModel.cs:

using ProductionScanner.Cores;
using ProductionScanner.MVVM.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Windows;
using System.Windows.Controls.Primitives;

namespace ProductionScanner.MVVM.ViewModel
{
    public class ReceiptViewModel: ObservableObject
    {
        private string _barcode;

        public string Barcode
        {
            get { return _barcode; }
            set { _barcode = value; OnPropertyChanged(); }
        }

        public RelayCommand ReceiptCommand { get; set; }
        public ReceiptViewModel()
        {
            ReceiptCommand = new RelayCommand(x =>
            {
                receiptInventory();
            });
        }

    private void receiptInventory()
    {
        if (Barcode.Length == 12)
        {
            var inventoryIDFrom = Barcode.Substring(0, 6);
            var kgIntFrom = Barcode.Substring(6);
            var kgDecimalFrom = kgIntFrom.Substring(0,kgIntFrom.Length-4)   "."   kgIntFrom.Substring(kgIntFrom.Length - 4, 3);
            ERPRestService _erpRestService = new ERPRestService();
            ReceiptItems receiptItems = new ReceiptItems();
            receiptItems.InventoryID = inventoryIDFrom;
            receiptItems.Qty = Convert.ToDecimal(kgDecimalFrom);
            receiptItems.WarehouseID = "WH001";
            receiptItems.LocationID = "L001";
            receiptItems.LotSerialNbr = "";
            receiptItems.ExpirationDate = DateTime.Now;
            try
            {
                var jsonObj1 = new
                {
                    Description = new
                    {
                        value = "Receipt"
                    },
                    Hold = new
                    {
                        value = false
                    },
                    Details = new[]
                    {
                    new {
                        InventoryID = new
                        {
                            value = receiptItems.InventoryID
                        },
                        Qty = new
                        {
                            value = receiptItems.Qty
                        },
                        WarehouseID = new
                        {
                            value = receiptItems.WarehouseID
                        },
                        Location = new
                        {
                            value = receiptItems.LocationID
                        }
                    }
                }

                };
                string entityAsString = JsonConvert.SerializeObject(jsonObj1);
                //string parameters1 = "$expand=Details";
                var receipt = _erpRestService.Put("InventoryReceipt", null, entityAsString);
                string refRelease = JObject.Parse(receipt)["ReferenceNbr"]["value"].ToString();
                var release = new
                {
                    entity = new
                    {
                        ReferenceNbr = new
                        {
                            value = refRelease
                        }
                    }
                };
                string jsonRelease = JsonConvert.SerializeObject(release);
                jsonRelease = _erpRestService.Post("InventoryReceipt", "ReleaseInventoryReceipt", jsonRelease);
                MessageBox.Show("Your AR Confirm has completed.", "Confirm", MessageBoxButton.OK, MessageBoxImage.Information);
            }

            
            catch (Exception ex)
            {
                throw (ex);
            }
            finally
            {
                _erpRestService.Dispose();

                
            }
        }
    }
}

}

CodePudding user response:

I tried a simplified version of the markup and code. The messagebox looked a bit suspicious to me as I was thinking it might take focus. What might happen after that.

Use of return was also a concern as I wondered what else return might do.

There's nowhere else for the focus to go.

If I just press tab then the cursor is still in the textbox.

My experimental markup:

<Window.DataContext>
    <local:MainWindowViewModel/>
</Window.DataContext>
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="25" />
        <RowDefinition/>
    </Grid.RowDefinitions>

    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>

    <Grid Background="#0F0F2D"
      Grid.ColumnSpan="2">

        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>

        </Grid.ColumnDefinitions>

        <TextBlock Text="Foods"
               Foreground="White"
               Grid.Column="1"
               VerticalAlignment="Center"
               HorizontalAlignment="Left"
               />
        <TextBlock Text="Records"
               Foreground="White"
               Grid.Column="2"
               VerticalAlignment="Center"
               HorizontalAlignment="Center"
               />
    </Grid>
    <StackPanel FocusManager.FocusedElement="{Binding ElementName=txtIniFocus}">
            <TextBox x:Name="txtIniFocus" Margin="6" Text="{Binding Barcode, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center" TextWrapping="Wrap" VerticalAlignment="Top" Width="150" Grid.Row="1">
                <TextBox.InputBindings>
                    <KeyBinding Key="Enter" Command="{Binding ReceiptCommand}" />
                </TextBox.InputBindings>
            </TextBox>
    </StackPanel>
</Grid>
</Window>

My viewmodel

public partial class MainWindowViewModel : ObservableObject
{
    [ObservableProperty]
    private string barcode = "65765765";

    [RelayCommand]
    private async Task Receipt()
    {
        // Your receipt processing would go here
        MessageBox.Show("Your AR Confirm has completed.", "Confirm", MessageBoxButton.OK, MessageBoxImage.Information);
        Barcode=string.Empty;
    }
}

I hit enter, the messagebox shows. I click OK. The messagebox closes, textbox is empty and the cursor is in the textbox.

If what you've shown us was all you have then I think setting Barcode to string.Empty would probably work.

Not sure it'd make much difference but my property changed notification is from the community toolkit mvvm and using the code generator. It will check for equality before raising property changed.

I'm not sure what your observableobject is there.

I still think the messagebox is a bad idea as the user has to pick the mouse up and click. An on screen indicator would be something to consider instead.

FWIW

I would also recommend just checking the length is 12 and drive the processing that way.

If you do both then the user could just scan, the receipt is done, scan the next receipt is done, scan....

They wouldn't have to touch keyboard or mouse.

That's the approach I've used for warehouse and product scanning on what sound like similar apps.

  • Related