我使用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); } }
}
}
答案 0 :(得分:0)
我发现您的代码有两个问题:
1。)_QRText = result.Text
不会为绑定触发PropertyChange。
2。)主要区别在于页面&#39; NavigationCacheMode
财产。您在NavigationCacheMode.Enabled
使用MainPage
,NavigationCacheMode.Disabled
使用DesignPage
。
在后台,ZXing会进行页面导航,然后进行后退导航,因此当它导航回MainPage
时,它会使用缓存版本,因此ViewModel也会被缓存。
但是在DesignPage
中禁用了缓存,因此后退导航会创建一个新页面并查看模型实例,因此在旧视图模型中调用以下代码,而不是在新模型中调用之一。
//Start scanning
var result = await scanner.Scan();
if (result != null)
_QRText = result.Text;
因此,您需要将页面的NavigationCacheMode
属性设置为启动QR码扫描的NavigationCacheMode.Required
。