UWP/Win10新特性系列—UserConsentVerifier

在UWP开发中,微软提供了新的用户许可验证方式-指纹(生物识别)、Pin、密码验证。在爆料的新型Win10 Mobile移动设备中,会增加虹膜识别等先进的用户身份识别技术,微软现在统一了身份验证的API,将生物识别认证和传统的密码识别封装为系统API供开发者调用,调用者只需关心认证的结果,而无需担心用户使用的是虹膜识别还是指纹还是密码等其他的识别技术。

通过UserConsentVerifier类可以提高应用程序的安全性,例如,你可以授权应用程序的购买,或者访问受限制的资源之前需要指纹验证。下面看下的UserConsentVerifier类结构。

Windows.Security.Credentials.UI. UserConsentVerifier 类中,微软提供了两个静态方法:

public static IAsyncOperation<UserConsentVerifierAvailability> CheckAvailabilityAsync();

public static IAsyncOperation<UserConsentVerificationResult> RequestVerificationAsync(System.String message);

CheckAvailabilityAsync()方法是用来检测用户的身份识别器是否可用

RequestVerificationAsync() 方法是请求用户身份识别,参数为身份验证对话框的提示语

下面我们使用个例子展示下这个新的识别技术的使用。

首先我们创建一个页面,使用SplitView做一个带有汉堡包菜单的页面MainPage.xaml

 1 <Page.Resources>
 2             <local:ScenarioBindingConverter x:Key="ScenarioConverter"></local:ScenarioBindingConverter>
 3         </Page.Resources>
 4
 5      <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
 6         <Grid.ColumnDefinitions>
 7             <ColumnDefinition Width="Auto"/>
 8             <ColumnDefinition Width="*"/>
 9         </Grid.ColumnDefinitions>
10         <VisualStateManager.VisualStateGroups>
11             <VisualStateGroup>
12                 <VisualState x:Name="wideState">
13                     <VisualState.StateTriggers>
14                         <AdaptiveTrigger MinWindowWidth="641" />
15                     </VisualState.StateTriggers>
16                     <VisualState.Setters>
17                         <Setter Target="Splitter.DisplayMode" Value="Inline"/>
18                     </VisualState.Setters>
19                 </VisualState>
20                 <VisualState x:Name="narrowState">
21                     <VisualState.StateTriggers>
22                         <AdaptiveTrigger MinWindowWidth="0" />
23                     </VisualState.StateTriggers>
24                     <VisualState.Setters>
25                         <Setter Target="Splitter.DisplayMode" Value="Overlay"/>
26                     </VisualState.Setters>
27                 </VisualState>
28             </VisualStateGroup>
29         </VisualStateManager.VisualStateGroups>
30         <SplitView x:Name="Splitter" IsPaneOpen="True" Grid.Column="1">
31             <SplitView.Pane>
32                 <RelativePanel Background="{ThemeResource SystemControlBackgroundChromeMediumBrush}">
33                     <StackPanel x:Name="HeaderPanel" Orientation="Horizontal">
34                         <TextBlock x:Name="Header" Text="Windows 10 sample" Style="{StaticResource TagLineTextStyle}" Margin="0,15,0,0" />
35                     </StackPanel>
36                     <TextBlock x:Name="SampleTitle" Text="Sample Title Here" Style="{StaticResource SampleHeaderTextStyle}" TextWrapping="Wrap" RelativePanel.Below="HeaderPanel" Margin="0,10,0,0"/>
37                     <ListBox x:Name="ScenarioControl" SelectionChanged="ScenarioControl_SelectionChanged"
38                  SelectionMode="Single" HorizontalAlignment="Left" Style="{StaticResource ScenarioListBoxStyle}"
39                  VerticalAlignment="Top" RelativePanel.Below="SampleTitle" Margin="0,10,0,0" >
40                         <ListBox.ItemTemplate>
41                             <DataTemplate>
42                                 <TextBlock Text="{Binding Converter={StaticResource ScenarioConverter}}" Style="{StaticResource ListItemTextStyle}"/>
43                             </DataTemplate>
44                         </ListBox.ItemTemplate>
45                     </ListBox>
46                 </RelativePanel>
47             </SplitView.Pane>
48             <RelativePanel>
49                 <Frame x:Name="ScenarioFrame" Margin="0,5,0,0" RelativePanel.AlignTopWithPanel="True" RelativePanel.Above="StatusPanel"/>
50                 <StackPanel x:Name="StatusPanel" Orientation="Vertical" RelativePanel.AlignBottomWithPanel="True">
51                     <TextBlock x:Name="StatusLabel" Margin="0,0,0,10" TextWrapping="Wrap" Text="Status:" />
52                     <Border x:Name="StatusBorder" Margin="0,0,0,0" Visibility="Collapsed" >
53                         <TextBlock x:Name="StatusBlock" FontWeight="Bold" MaxHeight="200" MinWidth="{Binding ElementName=Splitter, Path=ActualWidth}" TextTrimming="CharacterEllipsis"  Margin="20,10,10,20" TextWrapping="Wrap"/>
54                     </Border>
55                 </StackPanel>
56             </RelativePanel>
57         </SplitView>
58         <Border Background="{ThemeResource SystemControlBackgroundChromeMediumBrush}">
59             <ToggleButton Style="{StaticResource SymbolButton}" Click="Button_Click" VerticalAlignment="Top" Foreground="{ThemeResource ApplicationForegroundThemeBrush}">
60                 <ToggleButton.Content>
61                     <FontIcon x:Name="Hamburger" FontFamily="Segoe MDL2 Assets" Glyph="" Margin="0,10,0,0"/>
62                 </ToggleButton.Content>
63             </ToggleButton>
64         </Border>
65 </Grid>

上面用到的样式文件如下:

  1 <Style x:Key="SymbolButton" TargetType="ToggleButton">
  2       <Setter Property="Background" Value="{ThemeResource ToggleButtonBackgroundThemeBrush}"/>
  3       <Setter Property="Foreground" Value="{ThemeResource ToggleButtonForegroundThemeBrush}"/>
  4       <Setter Property="BorderBrush" Value="{ThemeResource ToggleButtonBorderThemeBrush}"/>
  5       <Setter Property="BorderThickness" Value="{ThemeResource ToggleButtonBorderThemeThickness}"/>
  6       <Setter Property="Padding" Value="12,4,12,5"/>
  7       <Setter Property="HorizontalAlignment" Value="Left"/>
  8       <Setter Property="VerticalAlignment" Value="Center"/>
  9       <Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
 10       <Setter Property="FontWeight" Value="SemiBold"/>
 11       <Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
 12       <Setter Property="Template">
 13           <Setter.Value>
 14               <ControlTemplate TargetType="ToggleButton">
 15                   <Grid>
 16                       <VisualStateManager.VisualStateGroups>
 17                           <VisualStateGroup x:Name="CommonStates">
 18                               <VisualState x:Name="Normal"/>
 19                               <VisualState x:Name="PointerOver">
 20                                   <Storyboard>
 21                                   </Storyboard>
 22                               </VisualState>
 23                               <VisualState x:Name="Pressed">
 24                                   <Storyboard>
 25                                       <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
 26                                           <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleButtonCheckedPressedBackgroundThemeBrush}"/>
 27                                       </ObjectAnimationUsingKeyFrames>
 28                                   </Storyboard>
 29                               </VisualState>
 30                               <VisualState x:Name="Disabled">
 31                                   <Storyboard>
 32                                       <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
 33                                           <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleButtonDisabledForegroundThemeBrush}"/>
 34                                       </ObjectAnimationUsingKeyFrames>
 35                                   </Storyboard>
 36                               </VisualState>
 37                               <VisualState x:Name="Checked">
 38                                   <Storyboard>
 39                                       <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
 40                                           <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleButtonCheckedBackgroundThemeBrush}"/>
 41                                       </ObjectAnimationUsingKeyFrames>
 42                                   </Storyboard>
 43                               </VisualState>
 44                               <VisualState x:Name="CheckedPointerOver">
 45                                   <Storyboard>
 46                                       <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
 47                                           <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleButtonCheckedPointerOverBackgroundThemeBrush}"/>
 48                                       </ObjectAnimationUsingKeyFrames>
 49                                   </Storyboard>
 50                               </VisualState>
 51                               <VisualState x:Name="CheckedPressed">
 52                                   <Storyboard>
 53                                       <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
 54                                           <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleButtonCheckedPressedBackgroundThemeBrush}"/>
 55                                       </ObjectAnimationUsingKeyFrames>
 56                                   </Storyboard>
 57                               </VisualState>
 58                               <VisualState x:Name="CheckedDisabled">
 59                                   <Storyboard>
 60                                       <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
 61                                           <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleButtonCheckedDisabledForegroundThemeBrush}"/>
 62                                       </ObjectAnimationUsingKeyFrames>
 63                                   </Storyboard>
 64                               </VisualState>
 65                               <VisualState x:Name="Indeterminate"/>
 66                               <VisualState x:Name="IndeterminatePointerOver">
 67                               </VisualState>
 68                               <VisualState x:Name="IndeterminatePressed">
 69                                   <Storyboard>
 70                                       <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
 71                                           <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleButtonPressedForegroundThemeBrush}"/>
 72                                       </ObjectAnimationUsingKeyFrames>
 73                                   </Storyboard>
 74                               </VisualState>
 75                               <VisualState x:Name="IndeterminateDisabled">
 76                                   <Storyboard>
 77                                       <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
 78                                           <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleButtonDisabledForegroundThemeBrush}"/>
 79                                       </ObjectAnimationUsingKeyFrames>
 80                                   </Storyboard>
 81                               </VisualState>
 82                           </VisualStateGroup>
 83                           <VisualStateGroup x:Name="FocusStates">
 84                               <VisualState x:Name="Focused">
 85                                   <Storyboard>
 86                                       <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="FocusVisualWhite"/>
 87                                       <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="FocusVisualBlack"/>
 88                                   </Storyboard>
 89                               </VisualState>
 90                               <VisualState x:Name="Unfocused"/>
 91                               <VisualState x:Name="PointerFocused"/>
 92                           </VisualStateGroup>
 93                       </VisualStateManager.VisualStateGroups>
 94                       <ContentPresenter x:Name="ContentPresenter" AutomationProperties.AccessibilityView="Raw" ContentTemplate="{TemplateBinding ContentTemplate}" ContentTransitions="{TemplateBinding ContentTransitions}" Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
 95                       <Rectangle x:Name="FocusVisualWhite" IsHitTestVisible="False" Opacity="0" StrokeDashOffset="1.5" StrokeEndLineCap="Square" Stroke="{ThemeResource FocusVisualWhiteStrokeThemeBrush}" StrokeDashArray="1,1"/>
 96                       <Rectangle x:Name="FocusVisualBlack" IsHitTestVisible="False" Opacity="0" StrokeDashOffset="0.5" StrokeEndLineCap="Square" Stroke="{ThemeResource FocusVisualBlackStrokeThemeBrush}" StrokeDashArray="1,1"/>
 97                   </Grid>
 98               </ControlTemplate>
 99           </Setter.Value>
100       </Setter>
101   </Style>
102
103   <Style x:Key="BasicTextStyle" TargetType="TextBlock" BasedOn="{StaticResource BaseTextBlockStyle}">
104       <Setter Property="FontWeight" Value="Normal"/>
105       <Setter Property="Margin" Value="0,0,0,10"/>
106   </Style>
107
108   <Style x:Key="TagLineTextStyle" TargetType="TextBlock">
109       <Setter Property="FontFamily" Value="Segoe UI Light"/>
110       <Setter Property="FontSize" Value="16"/>
111   </Style>
112
113   <Style x:Key="SampleHeaderTextStyle" TargetType="TextBlock">
114       <Setter Property="FontFamily" Value="Segoe UI Light"/>
115       <Setter Property="FontSize" Value="26.667"/>
116   </Style>
117
118   <Style x:Key="ListItemTextStyle" TargetType="TextBlock">
119       <Setter Property="FontFamily" Value="Segoe UI Semilight"/>
120       <Setter Property="FontSize" Value="18"/>
121       <Setter Property="Margin" Value="10,0,0,0"/>
122       <Setter Property="Foreground" Value="White"/>
123       <Setter Property="TextWrapping" Value="Wrap"/>
124   </Style>
125
126   <Style x:Key="CopyrightTextStyle" TargetType="TextBlock" BasedOn="{StaticResource BaseTextBlockStyle}">
127       <Setter Property="FontWeight" Value="Normal"/>
128   </Style>
129
130   <Style x:Key="ScenarioHeaderTextStyle" TargetType="TextBlock">
131       <Setter Property="FontFamily" Value="Segoe UI Light"/>
132       <Setter Property="FontSize" Value="26.667"/>
133   </Style>
134
135   <Style x:Key="ScenarioDescriptionTextStyle" TargetType="TextBlock">
136       <Setter Property="FontFamily" Value="Segoe UI Light"/>
137       <Setter Property="FontSize" Value="16"/>
138   </Style>
139
140   <Style x:Key="BaseMessageStyle" TargetType="TextBlock">
141       <Setter Property="FontFamily" Value="Segoe UI Semilight"/>
142       <Setter Property="FontSize" Value="14.667"/>
143       <Setter Property="Margin" Value="0,0,0,5"/>
144   </Style>
145
146   <Style x:Key="SeparatorStyle" TargetType="TextBlock">
147       <Setter Property="FontFamily" Value="Segoe UI"/>
148       <Setter Property="FontSize" Value="9"/>
149       <Setter Property="Foreground" Value="Gray"/>
150   </Style>
151
152   <Style x:Key="HyperlinkStyle" TargetType="HyperlinkButton">
153       <Setter Property="Padding" Value="1"/>
154       <Setter Property="Foreground" Value="Gray"/>
155   </Style>
156
157   <!-- Default style for Windows.UI.Xaml.Controls.ListBoxItem -->
158   <Style x:Key="ListBoxItemStyle" TargetType="ListBoxItem">
159       <Setter Property="Background" Value="Transparent" />
160       <Setter Property="TabNavigation" Value="Local" />
161       <Setter Property="Padding" Value="8,10" />
162       <Setter Property="HorizontalContentAlignment" Value="Left" />
163       <Setter Property="Template">
164           <Setter.Value>
165               <ControlTemplate TargetType="ListBoxItem">
166                   <Border x:Name="LayoutRoot"
167                       Background="{TemplateBinding Background}"
168                       BorderBrush="{TemplateBinding BorderBrush}"
169                       BorderThickness="{TemplateBinding BorderThickness}">
170                       <VisualStateManager.VisualStateGroups>
171                           <VisualStateGroup x:Name="CommonStates">
172                               <VisualState x:Name="Normal" />
173                               <VisualState x:Name="PointerOver">
174                                   <Storyboard>
175                                       <ObjectAnimationUsingKeyFrames Storyboard.TargetName="LayoutRoot"
176                                                                  Storyboard.TargetProperty="Background">
177                                           <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListBoxItemPointerOverBackgroundThemeBrush}" />
178                                       </ObjectAnimationUsingKeyFrames>
179                                       <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
180                                                                  Storyboard.TargetProperty="Foreground">
181                                           <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListBoxItemPointerOverForegroundThemeBrush}" />
182                                       </ObjectAnimationUsingKeyFrames>
183                                   </Storyboard>
184                               </VisualState>
185                               <VisualState x:Name="Disabled">
186                                   <Storyboard>
187                                       <ObjectAnimationUsingKeyFrames Storyboard.TargetName="LayoutRoot"
188                                                                  Storyboard.TargetProperty="Background">
189                                           <DiscreteObjectKeyFrame KeyTime="0" Value="Transparent" />
190                                       </ObjectAnimationUsingKeyFrames>
191                                       <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
192                                                                  Storyboard.TargetProperty="Foreground">
193                                           <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListBoxItemDisabledForegroundThemeBrush}" />
194                                       </ObjectAnimationUsingKeyFrames>
195                                   </Storyboard>
196                               </VisualState>
197                               <VisualState x:Name="Pressed">
198                                   <Storyboard>
199                                       <DoubleAnimation Storyboard.TargetName="PressedBackground"
200                                                    Storyboard.TargetProperty="Opacity"
201                                                    To="1"
202                                                    Duration="0" />
203                                       <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
204                                                                  Storyboard.TargetProperty="Foreground">
205                                           <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListBoxItemPressedForegroundThemeBrush}" />
206                                       </ObjectAnimationUsingKeyFrames>
207                                   </Storyboard>
208                               </VisualState>
209                           </VisualStateGroup>
210                           <VisualStateGroup x:Name="SelectionStates">
211                               <VisualState x:Name="Unselected" />
212                               <VisualState x:Name="Selected">
213                                   <Storyboard>
214                                       <ObjectAnimationUsingKeyFrames Storyboard.TargetName="InnerGrid"
215                                                                  Storyboard.TargetProperty="Background">
216                                           <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListBoxItemSelectedBackgroundThemeBrush}" />
217                                       </ObjectAnimationUsingKeyFrames>
218                                       <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
219                                                                  Storyboard.TargetProperty="Foreground">
220                                           <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListBoxItemSelectedForegroundThemeBrush}" />
221                                       </ObjectAnimationUsingKeyFrames>
222                                   </Storyboard>
223                               </VisualState>
224                               <VisualState x:Name="SelectedUnfocused">
225                                   <Storyboard>
226                                       <ObjectAnimationUsingKeyFrames Storyboard.TargetName="InnerGrid"
227                                                                  Storyboard.TargetProperty="Background">
228                                           <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListBoxItemSelectedBackgroundThemeBrush}" />
229                                       </ObjectAnimationUsingKeyFrames>
230                                       <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
231                                                                  Storyboard.TargetProperty="Foreground">
232                                           <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListBoxItemSelectedForegroundThemeBrush}" />
233                                       </ObjectAnimationUsingKeyFrames>
234                                   </Storyboard>
235                               </VisualState>
236                               <VisualState x:Name="SelectedDisabled">
237                                   <Storyboard>
238                                       <ObjectAnimationUsingKeyFrames Storyboard.TargetName="InnerGrid"
239                                                                  Storyboard.TargetProperty="Background">
240                                           <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListBoxItemSelectedDisabledBackgroundThemeBrush}" />
241                                       </ObjectAnimationUsingKeyFrames>
242                                       <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
243                                                                  Storyboard.TargetProperty="Foreground">
244                                           <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListBoxItemSelectedDisabledForegroundThemeBrush}" />
245                                       </ObjectAnimationUsingKeyFrames>
246                                   </Storyboard>
247                               </VisualState>
248                               <VisualState x:Name="SelectedPointerOver">
249                                   <Storyboard>
250                                       <ObjectAnimationUsingKeyFrames Storyboard.TargetName="InnerGrid"
251                                                                  Storyboard.TargetProperty="Background">
252                                           <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListBoxItemSelectedPointerOverBackgroundThemeBrush}" />
253                                       </ObjectAnimationUsingKeyFrames>
254                                       <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
255                                                                  Storyboard.TargetProperty="Foreground">
256                                           <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListBoxItemSelectedForegroundThemeBrush}" />
257                                       </ObjectAnimationUsingKeyFrames>
258                                   </Storyboard>
259                               </VisualState>
260                               <VisualState x:Name="SelectedPressed">
261                                   <Storyboard>
262                                       <ObjectAnimationUsingKeyFrames Storyboard.TargetName="InnerGrid"
263                                                                  Storyboard.TargetProperty="Background">
264                                           <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListBoxItemSelectedBackgroundThemeBrush}" />
265                                       </ObjectAnimationUsingKeyFrames>
266                                       <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
267                                                                  Storyboard.TargetProperty="Foreground">
268                                           <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListBoxItemSelectedForegroundThemeBrush}" />
269                                       </ObjectAnimationUsingKeyFrames>
270                                   </Storyboard>
271                               </VisualState>
272                           </VisualStateGroup>
273                           <VisualStateGroup x:Name="FocusStates">
274                               <VisualState x:Name="Focused">
275                                   <Storyboard>
276                                       <DoubleAnimation Storyboard.TargetName="FocusVisualWhite"
277                                                    Storyboard.TargetProperty="Opacity"
278                                                    To="1"
279                                                    Duration="0" />
280                                       <DoubleAnimation Storyboard.TargetName="FocusVisualBlack"
281                                                    Storyboard.TargetProperty="Opacity"
282                                                    To="1"
283                                                    Duration="0" />
284                                   </Storyboard>
285                               </VisualState>
286                               <VisualState x:Name="Unfocused" />
287                               <VisualState x:Name="PointerFocused" />
288                           </VisualStateGroup>
289                       </VisualStateManager.VisualStateGroups>
290                       <Grid x:Name="InnerGrid"
291                         Background="Transparent">
292                           <Rectangle x:Name="PressedBackground"
293                                  Fill="{ThemeResource ListBoxItemPressedBackgroundThemeBrush}"
294                                  Opacity="0" />
295                           <ContentPresenter x:Name="ContentPresenter"
296                                         Content="{TemplateBinding Content}"
297                                         ContentTransitions="{TemplateBinding ContentTransitions}"
298                                         ContentTemplate="{TemplateBinding ContentTemplate}"
299                                         HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
300                                         VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
301                                         Margin="{TemplateBinding Padding}" />
302                           <Rectangle x:Name="FocusVisualWhite"
303                                  Stroke="{ThemeResource FocusVisualWhiteStrokeThemeBrush}"
304                                  StrokeEndLineCap="Square"
305                                  StrokeDashArray="1,1"
306                                  Opacity="0"
307                                  StrokeDashOffset=".5" />
308                           <Rectangle x:Name="FocusVisualBlack"
309                                  Stroke="{ThemeResource FocusVisualBlackStrokeThemeBrush}"
310                                  StrokeEndLineCap="Square"
311                                  StrokeDashArray="1,1"
312                                  Opacity="0"
313                                  StrokeDashOffset="1.5" />
314                       </Grid>
315                   </Border>
316               </ControlTemplate>
317           </Setter.Value>
318       </Setter>
319   </Style>
320
321
322   <Style x:Key="ScenarioListBoxStyle" TargetType="ListBox">
323       <Setter Property="Foreground" Value="{ThemeResource ListBoxForegroundThemeBrush}"/>
324       <Setter Property="Background" Value="Transparent"/>
325       <Setter Property="BorderBrush" Value="Transparent"/>
326       <Setter Property="BorderThickness" Value="{ThemeResource ListBoxBorderThemeThickness}"/>
327       <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
328       <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
329       <Setter Property="ScrollViewer.HorizontalScrollMode" Value="Disabled"/>
330       <Setter Property="ScrollViewer.IsHorizontalRailEnabled" Value="True"/>
331       <Setter Property="ScrollViewer.VerticalScrollMode" Value="Enabled"/>
332       <Setter Property="ScrollViewer.IsVerticalRailEnabled" Value="True"/>
333       <Setter Property="ScrollViewer.ZoomMode" Value="Disabled"/>
334       <Setter Property="ScrollViewer.IsDeferredScrollingEnabled" Value="False"/>
335       <Setter Property="ScrollViewer.BringIntoViewOnFocusChange" Value="True"/>
336       <Setter Property="IsTabStop" Value="False"/>
337       <Setter Property="TabNavigation" Value="Once"/>
338       <Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
339       <Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
340       <Setter Property="ItemsPanel">
341           <Setter.Value>
342               <ItemsPanelTemplate>
343                   <VirtualizingStackPanel Background="Transparent"/>
344               </ItemsPanelTemplate>
345           </Setter.Value>
346       </Setter>
347       <Setter Property="Template">
348           <Setter.Value>
349               <ControlTemplate TargetType="ListBox">
350                   <Border x:Name="LayoutRoot" BorderBrush="Transparent" BorderThickness="{TemplateBinding BorderThickness}" Background="Transparent">
351                       <VisualStateManager.VisualStateGroups>
352                           <VisualStateGroup x:Name="CommonStates">
353                               <VisualState x:Name="Normal"/>
354                               <VisualState x:Name="Disabled">
355                                   <Storyboard>
356                                       <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="LayoutRoot">
357                                           <DiscreteObjectKeyFrame KeyTime="0" Value="Transparent"/>
358                                       </ObjectAnimationUsingKeyFrames>
359                                   </Storyboard>
360                               </VisualState>
361                           </VisualStateGroup>
362                           <VisualStateGroup x:Name="FocusStates">
363                               <VisualState x:Name="Focused">
364                                   <Storyboard>
365                                       <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="LayoutRoot">
366                                           <DiscreteObjectKeyFrame KeyTime="0" Value="Transparent"/>
367                                       </ObjectAnimationUsingKeyFrames>
368                                   </Storyboard>
369                               </VisualState>
370                               <VisualState x:Name="Unfocused"/>
371                           </VisualStateGroup>
372                       </VisualStateManager.VisualStateGroups>
373                       <ScrollViewer x:Name="ScrollViewer" AutomationProperties.AccessibilityView="Raw" BringIntoViewOnFocusChange="{TemplateBinding ScrollViewer.BringIntoViewOnFocusChange}" HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}" HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}" IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}" IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}" Padding="{TemplateBinding Padding}" TabNavigation="{TemplateBinding TabNavigation}" VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}" VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}" ZoomMode="{TemplateBinding ScrollViewer.ZoomMode}">
374                           <ItemsPresenter/>
375                       </ScrollViewer>
376                   </Border>
377               </ControlTemplate>
378           </Setter.Value>
379       </Setter>
380   </Style>

然后在App.xaml.cs中引用我们创建好的样式文件,这样MainPage.xaml就可以使用该外部样式文件里面的样式了。

1 <Application.Resources>
2        <ResourceDictionary>
3            <ResourceDictionary.MergedDictionaries>
4                <ResourceDictionary Source="/Styles/Styles.xaml"/>
5            </ResourceDictionary.MergedDictionaries>
6        </ResourceDictionary>
7    </Application.Resources>

接着创建菜单项的Model,创建一个类Scenario:

1 public class Scenario
2 {
3     public string Title { get; set; }
4     public Type ClassType { get; set; }
5 }

然后在MainPage.xaml.cs中实现跳转的逻辑:

 1 public sealed partial class MainPage : Page
 2     {
 3         public static MainPage Current;
 4         public const string FEATURE_NAME = "User Consent Verifier";
 5
 6         List<Scenario> scenarios = new List<Scenario>
 7         {
 8             new Scenario() { Title="Check Consent Availability", ClassType=typeof(Scenario1_CheckConsentAvailability)},
 9             new Scenario() { Title="Request Consent", ClassType=typeof(Scenario2_RequestConsent)}
10         };
11
12         public MainPage()
13         {
14             this.InitializeComponent();
15             Current = this;
16             SampleTitle.Text = FEATURE_NAME;
17         }
18
19         protected override void OnNavigatedTo(NavigationEventArgs e)
20         {
21             ScenarioControl.ItemsSource = scenarios;
22             if (Window.Current.Bounds.Width < 640)
23             {
24                 ScenarioControl.SelectedIndex = -1;
25             }
26             else
27             {
28                 ScenarioControl.SelectedIndex = 0;
29             }
30         }
31
32         private void ScenarioControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
33         {
34             NotifyUser(String.Empty, NotifyType.StatusMessage);
35
36             ListBox scenarioListBox = sender as ListBox;
37             Scenario s = scenarioListBox.SelectedItem as Scenario;
38             if (s != null)
39             {
40                 ScenarioFrame.Navigate(s.ClassType);
41                 if (Window.Current.Bounds.Width < 640)
42                 {
43                     Splitter.IsPaneOpen = false;
44                     StatusBorder.Visibility = Visibility.Collapsed;
45                 }
46             }
47         }
48
49         public List<Scenario> Scenarios
50         {
51             get { return this.scenarios; }
52         }
53
54         public void NotifyUser(string strMessage, NotifyType type)
55         {
56             switch (type)
57             {
58                 case NotifyType.StatusMessage:
59                     StatusBorder.Background = new SolidColorBrush(Windows.UI.Colors.Green);
60                     break;
61                 case NotifyType.ErrorMessage:
62                     StatusBorder.Background = new SolidColorBrush(Windows.UI.Colors.Red);
63                     break;
64             }
65             StatusBlock.Text = strMessage;
66             StatusBorder.Visibility = (StatusBlock.Text != String.Empty) ? Visibility.Visible : Visibility.Collapsed;
67         }
68
69         private void Button_Click(object sender, RoutedEventArgs e)
70         {
71             Splitter.IsPaneOpen = (Splitter.IsPaneOpen == true) ? false : true;
72             StatusBorder.Visibility = Visibility.Collapsed;
73         }
74     }
75     public enum NotifyType
76     {
77         StatusMessage,
78         ErrorMessage
79     };
80
81     public class ScenarioBindingConverter : IValueConverter
82     {
83         public object Convert(object value, Type targetType, object parameter, string language)
84         {
85             Scenario s = value as Scenario;
86             return (MainPage.Current.Scenarios.IndexOf(s) + 1) + ") " + s.Title;
87         }
88
89         public object ConvertBack(object value, Type targetType, object parameter, string language)
90         {
91             return true;
92         }
93 }

至此,首页已经完工,一个带有汉堡包菜单的主页,然后我们创建检测用户身份验证器是否可用的页面Scenario1_CheckConsentAvailability.xaml,前台代码如下:

 1 <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
 2         <Grid x:Name="RootGrid" Margin="12,20,12,12">
 3             <Grid.RowDefinitions>
 4                 <RowDefinition Height="Auto"/>
 5                 <RowDefinition Height="*"/>
 6                 <RowDefinition Height="Auto"/>
 7             </Grid.RowDefinitions>
 8             <StackPanel Margin="0,0,0,10">
 9                 <TextBlock Text="Description:" Style="{StaticResource SampleHeaderTextStyle}"/>
10                 <TextBlock Style="{StaticResource ScenarioDescriptionTextStyle}" TextWrapping="Wrap">
11                     检测用户的身份验证器是否可以使用
12                 </TextBlock>
13             </StackPanel>
14
15             <ScrollViewer Grid.Row="1" VerticalScrollMode="Auto" VerticalScrollBarVisibility="Auto">
16                 <StackPanel Orientation="Vertical" VerticalAlignment="Top">
17                     <StackPanel Orientation="Horizontal" Margin="0,10,0,0" Grid.Row="1">
18                         <Button x:Name="CheckAvailability" Content="Check Availability" Margin="0,0,10,0" Click="CheckAvailability_Click"/>
19                     </StackPanel>
20                 </StackPanel>
21             </ScrollViewer>
22
23             <Border x:Name="ErrorBorder" Background="Red" Grid.Row="2"/>
24             <TextBlock x:Name="StatusBlock" Grid.Row="2" Margin="12, 10, 12, 10" Visibility="Collapsed"/>
25         </Grid>
26     </Grid>

后台实现检测用户身份验证器是否可用的代码:

 1     private async void CheckAvailability_Click(object sender, RoutedEventArgs e)
 2       {
 3           Button b = sender as Button;
 4           b.IsEnabled = false;
 5           try
 6           {
 7               UserConsentVerifierAvailability consentAvailability = await Windows.Security.Credentials.UI.UserConsentVerifier.CheckAvailabilityAsync();
 8               switch (consentAvailability)
 9               {
10                   case UserConsentVerifierAvailability.Available:
11                       {
12                           rootPage.NotifyUser("用户身份验证器可用", NotifyType.StatusMessage);
13                           break;
14                       }
15
16                   case UserConsentVerifierAvailability.DeviceBusy:
17                       {
18                           rootPage.NotifyUser("验证器正忙或不可用", NotifyType.ErrorMessage);
19                           break;
20                       }
21
22                   case UserConsentVerifierAvailability.DeviceNotPresent:
23                       {
24                           rootPage.NotifyUser("没有发现验证设备", NotifyType.ErrorMessage);
25                           break;
26                       }
27
28                   case UserConsentVerifierAvailability.DisabledByPolicy:
29                       {
30                           rootPage.NotifyUser("策略组禁用了生物验证", NotifyType.ErrorMessage);
31                           break;
32                       }
33
34                   case UserConsentVerifierAvailability.NotConfiguredForUser:
35                       {
36                           rootPage.NotifyUser("该用户没有配置验证信息", NotifyType.ErrorMessage);
37                           break;
38                       }
39
40                   default:
41                       {
42                           rootPage.NotifyUser("验证器不可用", NotifyType.ErrorMessage);
43                           break;
44                       }
45               }
46           }
47           catch (Exception ex)
48           {
49               rootPage.NotifyUser("验证器出错了, Exception: " + ex.ToString(), NotifyType.ErrorMessage);
50           }
51           finally
52           {
53               b.IsEnabled = true;
54           }
55 }

验证页面完毕,创建请求身份验证的页面Scenario2_RequestConsent.xaml,前台代码如下:

 1 <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
 2        <Grid x:Name="RootGrid" Margin="12,20,12,12">
 3            <Grid.RowDefinitions>
 4                <RowDefinition Height="Auto"/>
 5                <RowDefinition Height="*"/>
 6                <RowDefinition Height="Auto"/>
 7            </Grid.RowDefinitions>
 8            <StackPanel Margin="0,0,0,10">
 9                <TextBlock Text="Description:" Style="{StaticResource SampleHeaderTextStyle}"/>
10                <TextBlock Style="{StaticResource ScenarioDescriptionTextStyle}" TextWrapping="Wrap">
11                    请求身份验证并发送一个消息给用户
12                </TextBlock>
13            </StackPanel>
14
15            <ScrollViewer Grid.Row="1" VerticalScrollMode="Auto" VerticalScrollBarVisibility="Auto">
16                <StackPanel Orientation="Vertical" VerticalAlignment="Top">
17                    <StackPanel Orientation="Horizontal" Margin="0,10,0,0">
18                        <TextBlock Text="Message:" VerticalAlignment="Center" Width="85"/>
19                        <TextBox x:Name="Message" Text="Message to user" Width="300"/>
20                    </StackPanel>
21                    <StackPanel Orientation="Horizontal" Margin="0,10,0,0">
22                        <Button x:Name="RequestConsent" Content="Request Consent" Margin="85,0,0,0" Click="RequestConsent_Click"/>
23                    </StackPanel>
24                </StackPanel>
25            </ScrollViewer>
26
27            <Border x:Name="ErrorBorder" Background="Red" Grid.Row="2"/>
28            <TextBlock x:Name="StatusBlock" Grid.Row="2" Margin="12, 10, 12, 10" Visibility="Collapsed"/>
29        </Grid>
30    </Grid>

后台请求验证的代码:

 1 private async void RequestConsent_Click(object sender, RoutedEventArgs e)
 2      {
 3          Button b = sender as Button;
 4          b.IsEnabled = false;
 5
 6          if (!String.IsNullOrEmpty(Message.Text))
 7          {
 8              try
 9              {
10                  UserConsentVerificationResult consentResult = await Windows.Security.Credentials.UI.UserConsentVerifier.RequestVerificationAsync(Message.Text);
11                  switch (consentResult)
12                  {
13                      case UserConsentVerificationResult.Verified:
14                          {
15                              rootPage.NotifyUser("用户已通过验证", NotifyType.StatusMessage);
16                              break;
17                          }
18
19                      case UserConsentVerificationResult.DeviceBusy:
20                          {
21                              rootPage.NotifyUser("验证器正在忙或者不可用", NotifyType.ErrorMessage);
22                              break;
23                          }
24
25                      case UserConsentVerificationResult.DeviceNotPresent:
26                          {
27                              rootPage.NotifyUser("没有发现验证设备", NotifyType.ErrorMessage);
28                              break;
29                          }
30
31                      case UserConsentVerificationResult.DisabledByPolicy:
32                          {
33                              rootPage.NotifyUser("策略组禁用了生物验证", NotifyType.ErrorMessage);
34                              break;
35                          }
36
37                      case UserConsentVerificationResult.NotConfiguredForUser:
38                          {
39                              rootPage.NotifyUser("该用户没有配置验证信息", NotifyType.ErrorMessage);
40                              break;
41                          }
42
43                      case UserConsentVerificationResult.RetriesExhausted:
44                          {
45                              rootPage.NotifyUser("经过10次失败的验证后,没有经过验证", NotifyType.ErrorMessage);
46                              break;
47                          }
48                      case UserConsentVerificationResult.Canceled:
49                          {
50                              rootPage.NotifyUser("取消验证", NotifyType.ErrorMessage);
51                              break;
52                          }
53
54                      default:
55                          {
56                              rootPage.NotifyUser("不可用", NotifyType.ErrorMessage);
57                              break;
58                          }
59                  }
60              }
61              catch (Exception ex)
62              {
63                  rootPage.NotifyUser("调用身份验证器出错, Exception: " + ex.ToString(), NotifyType.ErrorMessage);
64              }
65              finally
66              {
67                  b.IsEnabled = true;
68              }
69          }
70          else
71          {
72              rootPage.NotifyUser("文本框值为空", NotifyType.ErrorMessage);
73              b.IsEnabled = true;
74          }
75 }

Ok,来看下效果:

推荐一个UWP开发群:53078485 大家可以进来一起学习~~

时间: 2024-11-08 12:57:55

UWP/Win10新特性系列—UserConsentVerifier的相关文章

UWP/Win10新特性系列—App Service

Win10中,新增了一个很实用的新特性叫做App Service,App Service允许App不在前台运行的情况下提供出一个或多个对外服务供其他App使用,这看起来就好像Web开发中的Web Api. 通过对外提供服务的形式,可以使App更好的完成一些其他App所拥有的专业性操作,而不必自己再去实现服务所做的操作.一些企业用户可以提供复杂的服务,比如云识别和云存储来供开发者使用.这样使开发成本大大降低,也可以为服务提供商带来更多的用户.比如我们可以调用二维码识别服务(如下图,假设其他App提

Win10/UWP新特性系列—Launcher实现应用间的通信

UWP中,微软为Windows.System.Launcher启动器新增了很多的功能,以前只能启动App,打开指定扩展名文件,对uri协议的解析,以及当启动的应用没有安装时则会提示前往商店下载等. 如今,微软丰富了Launcher的功能,使用新的Launcher我们可以在App中实现调用文件资源管理器.App-To-App Server(应用对应用服务),Background Task Server App(后台任务处理服务App)还有设置页面调用. 一:Launcher.LaunchFolde

Win10/UWP新特性系列-GetPublisherCacheFolder

微软Windows Runtime App拥有很强的安全模型来防止不同App之间的数据获取和共享,也就是我们所说的"沙盒机制",每个App都运行在Windows沙盒中,App之间的数据是不会被别的App获取到的. 在UWP中,微软新增了GetPublisherCacheFolder —— 共享存储文件夹的机制,这个获取的共享存储文件夹并不是说打破了原有的"沙盒机制",而是指,同一个软件开发商发布的App之间,是允许访问一个共享的文件夹以及里面的内容.例如,多个应用程

Win10/UWP新特性系列—使用打印机

微软在Win10时代终于完成的设备系统的大统一,"56个民族,56支花……"(⊙o⊙)…,既然统一了,那么也就意味着API也统一了,所以在UWP中,我们就可以使用统一的打印API来为设备(包括移动设备)添加基于XAML的App打印功能.使用Windows.Graphics.Printing和Windows.UI.Xaml.Printing命名空间,就可以很方便的将打印功能添加到我们的应用中. 下面是个例子,我们需要打印一个购物清单,前台代码如下: 1 <Page.Resource

Win10/UWP新特性系列—电池报告

UWP中,新增了当节电模式开启时,App能获取到通知的API,通过响应电源条件的更改,比如咨询用户是否使用黑色背景等来帮助延长电池使用时间. 通过Windows.Devices.Power命名空间中的电池API,你可以了解到正在运行的设备所有的电池详细信息. 通过创建Battery对象来表示单个电池控制器或聚合的所有电池控制器,然后使用GetReport方法返回BatteryReport对象,该对象可指示响应电池的充电.容量和状态. 需要用到的资源: Battery:提供该设备的电池控制器信息类

Win10/UWP新特性—Drag&amp;Drop 拖出元素到其他App

在以前的文章中,写过微软新特性Drag&Drop,当时可能由于处于Win10预览版,使用的VS也是预览版,只实现了从桌面拖拽文件到UWP App中,没能实现从UWP拖拽元素到Desktop App & UWP App中.昨天重新研究了Win10 拖拽这一块,发现以前没能实现的功能,在正式版的环境下都可以实现了,做个笔记以防日后忘记. 在UWP中,想要拖动元素到Desktop或者另一个UWP App中,除了设置元素的CanDrag="True"我们要使用元素的DragSt

atitit。win7 win8 win9 win10 win11 新特性总结与战略规划

atitit.win7 win8 win9 win10  win11 新特性总结与战略规划 1. win7 1 1.1. 发布时间 2009年10月22日 1 1.2. 稳定性大幅提升,很少蓝屏死机 1 1.3. 很少损坏不能启动(只有一次,2年,多机) 1 1.4. PC也可以触摸 1 2. win8 新特性 2 2.1. 2012年2月29日 2 2.2. Metro界面跨平台(移动平台,) 2 2.3. 本文导航 2 2.4. U盘上也可运行 2 3. win9 新特性 3 3.1. wi

5.7新特性

1. 背景 MySQL 5.7在2015-10-21发布了GA版本,即5.7.9,目前小版本已经到了5.7.12.5.7新增了许多新的feature和优化,接下来一个系列,我们就一起来尝尝鲜.首先这次主要是预览feature的变化以及兼容性问题.后面的系列,会针对重要的feature展开来学习. 2 安全相关的特性 2.1 认证插件 mysql.user表中的plugin更改成not null,5.7开始不再支持mysql_old_password的认证插件,推荐全部使用mysql_native

Win10/UWP新特性—SharedStorageAccessManager 共享文件

首先先给大家推荐一个UWP/Win10开发者群:53078485  里面有很多大婶,还有很多学习资源,欢迎大家来一起讨论Win10开发! 在UWP开发中,微软提供了一个新的特性叫做SharedStorageAccessManager,它允许我们的App根据指定的文件生成一个FileToken来共享此文件,其他App可以使用SharedStorageAccessManager. RedeemTokenForFileAsync(fileToken);方法根据FileToken来获取到共享的文件.这样