模板10 Zxing.Mobile.Net

时间:2017-03-14 19:33:42

标签: xaml uwp zxing template10

我使用Template 10 Hamburger Template和Zxing.mobile.net库时遇到问题     “Template10”:“1.1.12”,     “ZXing.Net.Mobile”:“2.1.46”

如果我将以下代码添加到Mainpage和Viewmodel中,则扫描程序正常工作并将值绑定回TextBox但如果我将相同的代码添加到详细信息页面,则返回的代码将不会绑定。我做错了什么

MainPage.xaml中

   <Page x:Class="WindowsApp3.Views.MainPage"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:Behaviors="using:Template10.Behaviors"
          xmlns:Core="using:Microsoft.Xaml.Interactions.Core"
          xmlns:Interactivity="using:Microsoft.Xaml.Interactivity"
          xmlns:controls="using:Template10.Controls"
          xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
          xmlns:local="using:WindowsApp3.Views"
          xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
          xmlns:vm="using:WindowsApp3.ViewModels"
          mc:Ignorable="d">

        <Page.DataContext>
            <vm:MainPageViewModel x:Name="ViewModel" />
        </Page.DataContext>

        <RelativePanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

            <VisualStateManager.VisualStateGroups>
                <VisualStateGroup x:Name="AdaptiveVisualStateGroup">
                    <VisualState x:Name="VisualStateNarrow">
                        <VisualState.StateTriggers>
                            <AdaptiveTrigger MinWindowWidth="{StaticResource NarrowMinWidth}" />
                        </VisualState.StateTriggers>
                        <VisualState.Setters>
                            <!--  TODO: change properties for narrow view  -->
                            <Setter Target="stateTextBox.Text" Value="Narrow Visual State" />
                        </VisualState.Setters>
                    </VisualState>
                    <VisualState x:Name="VisualStateNormal">
                        <VisualState.StateTriggers>
                            <AdaptiveTrigger MinWindowWidth="{StaticResource NormalMinWidth}" />
                        </VisualState.StateTriggers>
                        <VisualState.Setters>
                            <!--  TODO: change properties for normal view  -->
                            <Setter Target="stateTextBox.Text" Value="Normal Visual State" />
                        </VisualState.Setters>
                    </VisualState>
                    <VisualState x:Name="VisualStateWide">
                        <VisualState.StateTriggers>
                            <AdaptiveTrigger MinWindowWidth="{StaticResource WideMinWidth}" />
                        </VisualState.StateTriggers>
                        <VisualState.Setters>
                            <!--  TODO: change properties for wide view  -->
                            <Setter Target="stateTextBox.Text" Value="Wide Visual State" />
                        </VisualState.Setters>
                    </VisualState>
                </VisualStateGroup>
            </VisualStateManager.VisualStateGroups>

            <controls:PageHeader x:Name="pageHeader"
                                 RelativePanel.AlignLeftWithPanel="True"
                                 RelativePanel.AlignRightWithPanel="True"
                                 RelativePanel.AlignTopWithPanel="True"
                                 Text="Main Page">

                <!--  secondary commands  -->
                <controls:PageHeader.SecondaryCommands>
                    <AppBarButton Click="{x:Bind ViewModel.GotoSettings}" Label="Settings" />
                    <AppBarButton Click="{x:Bind ViewModel.GotoPrivacy}" Label="Privacy" />
                    <AppBarButton Click="{x:Bind ViewModel.GotoAbout}" Label="About" />
                </controls:PageHeader.SecondaryCommands>

            </controls:PageHeader>

            <RelativePanel EntranceNavigationTransitionInfo.IsTargetElement="True"
                           RelativePanel.AlignBottomWithPanel="True"
                           RelativePanel.AlignLeftWithPanel="True"
                           RelativePanel.AlignRightWithPanel="True"
                           RelativePanel.Below="pageHeader">


                <controls:Resizer x:Name="parameterResizer" Margin="16,16,16,0">

                    <TextBox MinWidth="150"
                             MinHeight="62"
                             Header="Parameter to pass"
                             Text="{Binding Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                             TextWrapping="Wrap">
                        <Interactivity:Interaction.Behaviors>

                            <!--  enable submit on enter key  -->
                            <Behaviors:KeyBehavior Key="Enter">
                                <Core:CallMethodAction MethodName="GotoDetailsPage" TargetObject="{Binding}" />
                            </Behaviors:KeyBehavior>

                            <!--  focus on textbox when page loads  -->
                            <Core:EventTriggerBehavior>
                                <Behaviors:FocusAction />
                            </Core:EventTriggerBehavior>

                        </Interactivity:Interaction.Behaviors>
                    </TextBox>

                </controls:Resizer>

                <Button x:Name="submitButton"
                        Click="{x:Bind ViewModel.GotoDetailsPage}"
                        Content="Submit"
                        RelativePanel.AlignBottomWith="parameterResizer"
                        RelativePanel.RightOf="parameterResizer" />

                <TextBlock x:Name="stateTextBox"
                           Margin="16,16,0,0"
                           RelativePanel.AlignLeftWith="parameterResizer"
                           RelativePanel.Below="parameterResizer"
                           Text="Current Visual State" />



            <!--  content  -->
            <!--  content  -->
            <Button x:Name="loadButton"
                          HorizontalAlignment="Center"
                          Width="180"
                          Height="50"
                                RelativePanel.Below="stateTextBox"

                          Click="{x:Bind ViewModel.QRCodeCick}">
              <StackPanel Orientation="Horizontal">
                <SymbolIcon Width="48"
                                               VerticalAlignment="Center"
                                               Height="48"
                                                Symbol="Camera" />
                <TextBlock Margin="12,0,0,0"
                                               VerticalAlignment="Center"
                                               Text="Read QR Code" />
              </StackPanel>
            </Button>
            <TextBox x:Name="QRTextBox"
                     PlaceholderText="Enter Code"
                     Text="{x:Bind ViewModel.QRText,Mode=TwoWay}"
                    RelativePanel.Below="loadButton"
                     Margin="0,0,0,12"/>

        </RelativePanel>

        </RelativePanel>
    </Page>

MainPage.xaml.cs中

using System;
using WindowsApp3.ViewModels;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
using System.Collections.ObjectModel;

namespace WindowsApp3.Views
{
  public sealed partial class MainPage : Page
  {
    public MainPage()
    {
      InitializeComponent();
      NavigationCacheMode = Windows.UI.Xaml.Navigation.NavigationCacheMode.Enabled;
    }
  }
}

MagePageViewModel.cs

using Template10.Mvvm;
using System.Collections.Generic;
using System;
using System.Linq;
using System.Threading.Tasks;
using Template10.Services.NavigationService;
using Windows.UI.Xaml.Navigation;
using ZXing.Mobile;

namespace WindowsApp3.ViewModels
{
  public class MainPageViewModel : ViewModelBase
  {
    MobileBarcodeScanner scanner;

    public MainPageViewModel()
    {
      if (Windows.ApplicationModel.DesignMode.DesignModeEnabled)
      {
        Value = "Designtime value";
      }

      //Create a new instance of our scanner
      scanner = new MobileBarcodeScanner();

      // this.Dispatcher
      //    scanner.Dispatcher = this.Dispatcher;

    }

    string _Value = "Gas";
    public string Value { get { return _Value; } set { Set(ref _Value, value); } }

    public override async Task OnNavigatedToAsync(object parameter, NavigationMode mode, IDictionary<string, object> suspensionState)
    {
      if (suspensionState.Any())
      {
        Value = suspensionState[nameof(Value)]?.ToString();
      }
      await Task.CompletedTask;
    }

    public override async Task OnNavigatedFromAsync(IDictionary<string, object> suspensionState, bool suspending)
    {
      if (suspending)
      {
        suspensionState[nameof(Value)] = Value;
      }
      await Task.CompletedTask;
    }

    public override async Task OnNavigatingFromAsync(NavigatingEventArgs args)
    {
      args.Cancel = false;
      await Task.CompletedTask;
    }

    public void GotoDetailsPage() =>
        NavigationService.Navigate(typeof(Views.DetailPage), Value);

    public void GotoSettings() =>
        NavigationService.Navigate(typeof(Views.SettingsPage), 0);

    public void GotoPrivacy() =>
        NavigationService.Navigate(typeof(Views.SettingsPage), 1);

    public void GotoAbout() =>
        NavigationService.Navigate(typeof(Views.SettingsPage), 2);


    public async void QRCodeCick()
    {
      scanner.UseCustomOverlay = false;

      scanner.TopText = "Hold camera up to barcode";
      scanner.BottomText = "Camera will automatically scan barcode\r\n\r\nPress the 'Back' button to Cancel";

      //Start scanning
      var result = await scanner.Scan();

      if (result != null)
        _QRText = result.Text;
    }

    string _QRText;
    public string QRText { get { return _QRText; } set { Set(ref _QRText, value); } }

  }
}

Details.xaml

<Page x:Class="WindowsApp3.Views.DetailPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:Behaviors="using:Template10.Behaviors"
      xmlns:Core="using:Microsoft.Xaml.Interactions.Core"
      xmlns:Interactivity="using:Microsoft.Xaml.Interactivity"
      xmlns:controls="using:Template10.Controls"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:local="using:WindowsApp3.Views"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      xmlns:vm="using:WindowsApp3.ViewModels"
      x:Name="ThisPage"
      mc:Ignorable="d">

    <Page.DataContext>
        <vm:DetailPageViewModel x:Name="ViewModel" />
    </Page.DataContext>

    <RelativePanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="AdaptiveVisualStateGroup">
                <VisualState x:Name="VisualStateNarrow">
                    <VisualState.StateTriggers>
                        <AdaptiveTrigger MinWindowWidth="{StaticResource NarrowMinWidth}" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <!--  TODO: change properties for narrow view  -->
                    </VisualState.Setters>
                </VisualState>
                <VisualState x:Name="VisualStateNormal">
                    <VisualState.StateTriggers>
                        <AdaptiveTrigger MinWindowWidth="{StaticResource NormalMinWidth}" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <!--  TODO: change properties for normal view  -->
                    </VisualState.Setters>
                </VisualState>
                <VisualState x:Name="VisualStateWide">
                    <VisualState.StateTriggers>
                        <AdaptiveTrigger MinWindowWidth="{StaticResource WideMinWidth}" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <!--  TODO: change properties for wide view  -->
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>

        <!--  header  -->
        <controls:PageHeader x:Name="pageHeader"
                             Frame="{x:Bind Frame}"
                             RelativePanel.AlignLeftWithPanel="True"
                             RelativePanel.AlignRightWithPanel="True"
                             RelativePanel.AlignTopWithPanel="True"
                             Text="Detail Page" />

        <!--  content  -->
        <ScrollViewer EntranceNavigationTransitionInfo.IsTargetElement="True"
                      Padding="12,8,0,0"
                      RelativePanel.AlignBottomWithPanel="True"
                      RelativePanel.AlignLeftWithPanel="True"
                      RelativePanel.AlignRightWithPanel="True"
                      RelativePanel.Below="pageHeader"
                      VerticalScrollBarVisibility="Auto">
            <StackPanel>
                <TextBlock Style="{StaticResource TitleTextBlockStyle}" Text="You passed:" />
                <TextBlock Style="{StaticResource SubtitleTextBlockStyle}" Text="{x:Bind ViewModel.Value, Mode=OneWay, FallbackValue=DesigntimeValue}" />
        <Button x:Name="loadButton"
                      HorizontalAlignment="Center"
                      Width="180"
                      Height="50"

                      Click="{x:Bind ViewModel.QRCodeCick}">
          <StackPanel Orientation="Horizontal">
            <SymbolIcon Width="48"
                                           VerticalAlignment="Center"
                                           Height="48"
                                            Symbol="Camera" />
            <TextBlock Margin="12,0,0,0"
                                           VerticalAlignment="Center"
                                           Text="Read QR Code" />
          </StackPanel>
        </Button>
        <TextBox x:Name="QRTextBox"
                 PlaceholderText="Enter Code"
                 Text="{x:Bind ViewModel.QRText,Mode=TwoWay}"
                 Margin="0,0,0,12"/>
      </StackPanel>
        </ScrollViewer>

    </RelativePanel>
</Page>

DesignPage.xaml.cs

using WindowsApp3.ViewModels;
using Windows.UI.Xaml.Navigation;
using Windows.UI.Xaml.Controls;

namespace WindowsApp3.Views
{
  public sealed partial class DetailPage : Page
  {
    public DetailPage()
    {
      InitializeComponent();
      NavigationCacheMode = NavigationCacheMode.Disabled;
    }
  }
}

DesignViewModel.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Template10.Common;
using Template10.Mvvm;
using Template10.Services.NavigationService;
using Windows.UI.Xaml.Navigation;
using ZXing.Mobile;

    namespace WindowsApp3.ViewModels
    {
      public class DetailPageViewModel : ViewModelBase
      {
        MobileBarcodeScanner scanner;

        public DetailPageViewModel()
        {
          if (Windows.ApplicationModel.DesignMode.DesignModeEnabled)
          {
            Value = "Designtime value";
          }

          //Create a new instance of our scanner
          scanner = new MobileBarcodeScanner();

          // this.Dispatcher
          //    scanner.Dispatcher = this.Dispatcher;

        }

        private string _Value = "Default";
        public string Value { get { return _Value; } set { Set(ref _Value, value); } }

        public override async Task OnNavigatedToAsync(object parameter, NavigationMode mode, IDictionary<string, object> suspensionState)
        {
          Value = (suspensionState.ContainsKey(nameof(Value))) ? suspensionState[nameof(Value)]?.ToString() : parameter?.ToString();
          await Task.CompletedTask;
        }

        public override async Task OnNavigatedFromAsync(IDictionary<string, object> suspensionState, bool suspending)
        {
          if (suspending)
          {
            suspensionState[nameof(Value)] = Value;
          }
          await Task.CompletedTask;
        }

        public override async Task OnNavigatingFromAsync(NavigatingEventArgs args)
        {
          args.Cancel = false;
          await Task.CompletedTask;
        }

        public async void QRCodeCick()
        {
          scanner.UseCustomOverlay = false;

          scanner.TopText = "Hold camera up to barcode";
          scanner.BottomText = "Camera will automatically scan barcode\r\n\r\nPress the 'Back' button to Cancel";

          //Start scanning
          var result = await scanner.Scan();

          if (result != null)
            _QRText = result.Text;
        }

        string _QRText;
        public string QRText { get { return _QRText; } set { Set(ref _QRText, value); } }
      }
    }

1 个答案:

答案 0 :(得分:0)

我发现您的代码有两个问题:

1。)_QRText = result.Text不会为绑定触发PropertyChange。

2。)主要区别在于页面&#39; NavigationCacheMode财产。您在NavigationCacheMode.Enabled使用MainPageNavigationCacheMode.Disabled使用DesignPage

在后台,ZXing会进行页面导航,然后进行后退导航,因此当它导航回MainPage时,它会使用缓存版本,因此ViewModel也会被缓存。

但是在DesignPage中禁用了缓存,因此后退导航会创建一个新页面并查看模型实例,因此在视图模型中调用以下代码,而不是在新模型中调用之一。

//Start scanning
var result = await scanner.Scan();

if (result != null)
    _QRText = result.Text;

因此,您需要将页面的NavigationCacheMode属性设置为启动QR码扫描的NavigationCacheMode.Required