【问题标题】:WPF: How to autoreset/autorefresh the textbox after scanning barcode in WPF?WPF:如何在 WPF 中扫描条码后自动重置/自动刷新文本框?
【发布时间】:2023-01-30 20:15:36
【问题描述】:

我正在制作一个简单的 WPF 程序,用户基本上只需要使用 USB 条码扫描仪扫描条码,程序就会将数据直接发送到云 ERP。现在,该程序可以运行,但用户必须在扫描后手动单击文本框,清除数据并再次扫描。我只希望用户打开软件并继续使用他的条形码阅读器进行扫描,而不必手动擦除文本框数据。我怎样才能做到这一点?

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

并且,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();

                
            }
        }
    }
}

}

【问题讨论】:

  • 你不能在消息框后面做 Barcode = string.Empty 吗?或者我错过了什么?
  • @RyanThomas 我以前试过,没用:(
  • 您在 TextBox 和属性之间的绑定是否确实正常工作?我注意到此框上还有一个 TextChanged 事件,它的作用是什么?
  • 消息框将获得焦点。你应该失去那个。改为在文本块中显示您的消息。
  • 由于您有 UpdateSourceTrigger=PropertyChanged,您可以检查文本框中是否有 12 个字符,如果有则打印您的收据。失去命令。我认为如果您将焦点保留在文本框中,然后将 Barcode 设置为 string.empty 将允许您再次扫描它。一旦失去焦点,您就不会将下一个代码扫描到其中。

标签: c# .net wpf barcode


【解决方案1】:

我尝试了标记和代码的简化版本。 消息框对我来说看起来有点可疑,因为我认为它可能会引起关注。之后可能会发生什么。

return 的使用也是一个问题,因为我想知道 return 还能做什么。

没有其他地方可以集中注意力。

如果我只是按 Tab 键,那么光标仍在文本框中。

我的实验标记:

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

我的视图模型

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

我按回车键,消息框显示。我单击确定。消息框关闭,文本框为空,光标位于文本框中。

如果您向我们展示的是您所拥有的全部内容,那么我认为将 Barcode 设置为 string.Empty 可能会起作用。

不确定它会有多大区别,但我的属性更改通知来自社区工具包 mvvm 并使用代码生成器。它将在 raising property changed 之前检查是否相等。

我不确定你的 observableobject 在那里。

我仍然认为消息框不是一个好主意,因为用户必须拿起鼠标并单击。屏幕上的指示器将是需要考虑的事情。

FWIW

我还建议只检查长度是否为 12 并以这种方式驱动处理。

如果你两者都做,那么用户可以扫描,收据完成,扫描下一张收据完成,扫描....

他们不必触摸键盘或鼠标。

这就是我在听起来像类似应用程序的仓库和产品扫描中使用的方法。

【讨论】:

    猜你喜欢
    • 2012-12-09
    • 2014-08-04
    • 2011-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-31
    • 1970-01-01
    相关资源
    最近更新 更多