Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 有没有更好的方法使用条形码扫描仪?_C#_Uwp_Barcode Scanner - Fatal编程技术网

C# 有没有更好的方法使用条形码扫描仪?

C# 有没有更好的方法使用条形码扫描仪?,c#,uwp,barcode-scanner,C#,Uwp,Barcode Scanner,我目前正在UWP应用程序中使用条形码扫描仪。 为了实现它,我学习了一些关于微软文档的教程 它工作得很好,但不像我想让它工作 条形码扫描仪只能通过DataReceived事件获取值。 因此,当我想从条形码扫描仪返回一个值时,这是不可能的 我在这里注册扫描仪: private静态异步任务ClaimScanner() { bool res=假; 字符串选择器=条形码扫描仪。GetDeviceSelector(); 设备信息收集设备收集=等待 设备信息。FindAllAsync(选择器); 如果(_sc

我目前正在UWP应用程序中使用
条形码扫描仪
。 为了实现它,我学习了一些关于微软文档的教程

它工作得很好,但不像我想让它工作

条形码扫描仪只能通过
DataReceived
事件获取值。 因此,当我想从
条形码扫描仪
返回一个值时,这是不可能的

我在这里注册扫描仪:

private静态异步任务ClaimScanner()
{
bool res=假;
字符串选择器=条形码扫描仪。GetDeviceSelector();
设备信息收集设备收集=等待
设备信息。FindAllAsync(选择器);
如果(_scanner==null)
_scanner=等待条形码scanner.FromIdAsync(deviceCollection[0].Id);
如果(_scanner!=null)
{
if(_claimedBarcodeScanner==null)
_claimedBarcodeScanner=await_scanner.ClaimScannerSync();
if(_claimedBarcodeScanner!=null)
{
_claimedBarcodeScanner.DataReceived+=claimedBarcodeScanner\u DataReceivedAsync;
[...] 
}
}
}
一旦我收到数据,它就会触发该事件:

private static async void ClaimedBarcodeScanner\u DataReceivedAsync(ClaimedBarcodeScanner发送方,barcodescanner datareceivedeventargs args)
{
等待Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,()=>
{
如果(CurrentDataContext!=null&&CurrentDataContext可编辑)
{
IsCanable obj=(IsCanable)CurrentDataContext;
obj.NumSerie=CryptographicBuffer.ConvertBinaryToString(BinaryStringEncoding.Utf8,args.Report.ScandaLabel);
}
else if(CurrentDataContext!=null&&CurrentDataContext为Poste)
{
Poste p=(Poste)CurrentDataContext;
字符串代码=CryptographicBuffer.ConvertBinaryToString(BinaryStringEncoding.Utf8,args.Report.ScandaLabel);
p、 CodePoste=code.Substring(0,6);
}
});
}
如您所见,我被迫在该方法中执行所有操作(更新其他类的实例,等等)

目前,我正在调用ViewModel中的条形码扫描仪:

public void ScanPosteCodeAsync()
{
ScanBarcodeUtil(CurrentPoste);
}
但是我无法控制我的
CurrentPoste
实例,我要做的更像:

public void ScanPosteCodeAsync()
{
字符串returnedCode=BarcodeScannerUtil.ScanBarcodeUtil()
this.CurrentPoste.Code=返回的代码;
}

为了在我的ViewModel中使用返回的值,是否有任何方法返回扫描仪的值?

在使用MVVM时,WPF开发人员也有类似的模式,您需要获取/更新视图模型(VM)公开的模型。也许它们在数据库中。与其用难看的DB代码污染你漂亮的VM,不如将“服务”传递到VM中。现在,“serivce”并不一定意味着SOA/微服务,也许它只是不同项目中的另一个类。关键是你把所有的条形码都放在那里,当收到一些东西时,它可能会触发一个你的虚拟机监听的事件,或者它只是把它排在某个地方,让你的虚拟机通过服务接口请求


我已经在一个服务类中有了所有的条形码,这是一个问题,因为我不想让服务类更新我当前的模型。我遇到的主要问题是,我不知道如何使我的VM侦听DataReceived事件


嗯,从我所看到的,您的服务并没有与UWP MVVM解耦。对于该事件,您是否考虑过仅为VM客户端公开次要事件?我发现这对我很有效


像VM中的事件侦听接收到的数据事件

是的,但它不必是对物理
事件的侦听,只需键入概念即可。C#事件意味着可以有多个订阅者,这对条形码应用程序来说没有意义。应该只有一个前台读卡器

在这里,我将使用
Action
将条形码从
BarcodeScanner
传递到客户机,在本例中是VM。通过使用
操作
并将条形码处理移动到客户端,我们使
条形码扫描仪
完全不知道MVVM
Windows.ApplicationModel.Core.CoreApplication.MainView
与它不应该关心的东西进行了难以置信的耦合

首先,我们希望将所有内容解耦,因此首先是一个表示条形码扫描仪重要位的接口:

public interface IBarcodeScanner
{
    Task<bool> ClaimScannerAsync();
    void Subscribe(Action<string> callback);
    void Unsubscribe();
}
最后,条形码扫描仪的新外观:

public class BarcodeScanner : IBarcodeScanner
{
    /// <summary>
    /// The callback, it only makes sense for one client at a time
    /// </summary>
    private static Action<string> _callback; // <--- NEW

    public async Task<bool> ClaimScannerAsync()
    {
        // as per OP's post, not reproduced here
    }

    public void Subscribe(Action<string> callback) // <--- NEW
    {
        // it makes sense to have only one foreground barcode reader client at a time
        _callback = callback;
    }

    public void Unsubscribe() // <--- NEW
    {
        _callback = null;
    }

    private void ClaimedBarcodeScanner_DataReceivedAsync(ClaimedBarcodeScanner sender, BarcodeScannerDataReceivedEventArgs args)
    {
        if (_callback == null) // don't bother with ConvertBinaryToString if we don't need to
            return;

        // all we need do here is convert to a string and pass it to the client

        var barcode = CryptographicBuffer.ConvertBinaryToString(BinaryStringEncoding.Utf8,
                                                                args.Report.ScanDataLabel);

        _callback(barcode);

    }
}
公共类条形码扫描程序:IBarcodeScanner
{
/// 
///对于回调,一次只对一个客户端有意义
/// 

私有静态操作_callback;//在使用MVVM时,WPF开发人员也有类似的模式,您需要获取/更新VM公开的模型。它们可能在数据库中。与其用丑陋的DB代码污染您漂亮的VM,不如将“服务”传递到VM中。现在,“serivce”这并不一定意味着SOA/microservices,也许它只是另一个项目中的另一个类。关键是你把所有的条形码放在那里,当收到某个东西时,它可能会触发一个你的虚拟机侦听的事件,或者它只是把它排成队列,让你的虚拟机通过服务接口请求。我已经拥有了所有的服务类中的条形码代码,这是一个问题,因为我不想让服务类更新我当前的模型。我的主要问题是我不知道如何让我的虚拟机侦听
DataReceived
事件。从我所看到的情况来看,您的服务与UWP MVVM没有解耦。对于该事件,您考虑过exp仅为VM客户端关闭辅助事件
public async void OnWidgetExecuted()
{
    await _scanner.ClaimScannerAsync();
    _scanner.Subscribe(OnReceivedBarcode);
}

// Barcode scanner will call this method when a barcode is received
private void OnReceivedBarcode(string barcode)
{
    // update VM accordingly
}
public class BarcodeScanner : IBarcodeScanner
{
    /// <summary>
    /// The callback, it only makes sense for one client at a time
    /// </summary>
    private static Action<string> _callback; // <--- NEW

    public async Task<bool> ClaimScannerAsync()
    {
        // as per OP's post, not reproduced here
    }

    public void Subscribe(Action<string> callback) // <--- NEW
    {
        // it makes sense to have only one foreground barcode reader client at a time
        _callback = callback;
    }

    public void Unsubscribe() // <--- NEW
    {
        _callback = null;
    }

    private void ClaimedBarcodeScanner_DataReceivedAsync(ClaimedBarcodeScanner sender, BarcodeScannerDataReceivedEventArgs args)
    {
        if (_callback == null) // don't bother with ConvertBinaryToString if we don't need to
            return;

        // all we need do here is convert to a string and pass it to the client

        var barcode = CryptographicBuffer.ConvertBinaryToString(BinaryStringEncoding.Utf8,
                                                                args.Report.ScanDataLabel);

        _callback(barcode);

    }
}