如何验证 4 次连续按钮单击(WPF 应用程序)



我无法弄清楚: - 如何捕捉4次按钮点击并检查它们是否匹配正确的顺序,类似于输入4位数字的ATM借记卡PIN码

我有一个 WPF 应用程序,并添加了一个新的窗口,其中包含一个 PIN 键盘、数字 0-9、一个问号按钮(用作帮助按钮)、一个退格按钮(以防您单击了错误的数字)、顶部显示一个点而不是数字的文本框(Wingdings - 字母"l"),以及一个隐藏的文本块,如果数字未按正确的顺序输入,将显示不正确的 PIN 消息。目前,我只是对 4 位 PIN 码(例如 7410)进行硬编码,因为我的主要目标是学习如何捕获和验证按钮单击序列。由于我不将使用 Enter 键按钮,因此我想在单击最后一个数字并且顺序正确后立即继续下一页,否则显示 PIN 不正确的通知消息。我还将输入代码以不允许除鼠标单击工作之外的任何内容,并将 TextBox 限制为最多只允许 4 位数字。

我猜我需要一种在每次单击按钮时调用的方法,该方法跟踪序列并每次循环回去,直到以正确的顺序单击所有 4 个数字,然后转到下一页。对不起,如果我解释不好,还在学习,所以如果您需要更多详细信息,我会尽力提供更多。

提前谢谢你。

下面是 PIN 键盘的 xaml 代码。

<Border BorderThickness="1" BorderBrush="Black">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Border Background="Black" Height="50" Grid.ColumnSpan="3" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<TextBlock x:Name="PINTextBlock" Foreground="White" FontSize="18" FontFamily="Wingdings" VerticalAlignment="Center" HorizontalAlignment="Center" MaxWidth="4" />
</Border>
<TextBlock x:Name="ErrorMessageTextBlock" Foreground="Red" Visibility="Collapsed" Grid.ColumnSpan="3" Grid.Row="1" />
<StackPanel Orientation="Horizontal" Grid.Row="2">
<Button x:Name="SevenButton" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="50" Height="50" Click="SevenButton_Click" TabIndex="9">
<TextBlock Text="7" FontSize="24" FontWeight="Bold" />
</Button>
<Button x:Name="EightButton" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="50" Height="50" Click="EightButton_Click" TabIndex="10">
<TextBlock Text="8" FontSize="24" FontWeight="Bold" />
</Button>
<Button x:Name="NineButton" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="50" Height="50" Click="NineButton_Click" TabIndex="11">
<TextBlock Text="9" FontSize="24" FontWeight="Bold" />
</Button>
</StackPanel>
<StackPanel Orientation="Horizontal" Grid.Row="3">
<Button x:Name="FourButton" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="50" Height="50" Click="FourButton_Click" TabIndex="6">
<TextBlock Text="4" FontSize="24" FontWeight="Bold" />
</Button>
<Button x:Name="FiveButton" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="50" Height="50" Click="FiveButton_Click" TabIndex="7">
<TextBlock Text="5" FontSize="24" FontWeight="Bold" />
</Button>
<Button x:Name="SixButton" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="50" Height="50" Click="SixButton_Click" TabIndex="8">
<TextBlock Text="6" FontSize="24" FontWeight="Bold" />
</Button>
</StackPanel>
<StackPanel Orientation="Horizontal" Grid.Row="4">
<Button x:Name="OneButton" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="50" Height="50" Click="OneButton_Click" TabIndex="3">
<TextBlock Text="1" FontSize="24" FontWeight="Bold" />
</Button>
<Button x:Name="TwoButton" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="50" Height="50" Click="TwoButton_Click" TabIndex="4">
<TextBlock Text="2" FontSize="24" FontWeight="Bold" />
</Button>
<Button x:Name="ThreeButton" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="50" Height="50" Click="ThreeButton_Click" TabIndex="5">
<TextBlock Text="3" FontSize="24" FontWeight="Bold" />
</Button>
</StackPanel>
<StackPanel Orientation="Horizontal" Grid.Row="5">
<Button x:Name="QuestionMarkButton" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="50" Height="50" Click="QuestionMarkButton_Click" TabIndex="0">
<TextBlock Text="?" FontSize="24" FontWeight="Bold" />
</Button>
<Button x:Name="ZeroButton" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="50" Height="50" Click="ZeroButton_Click" TabIndex="1">
<TextBlock Text="0" FontSize="24" FontWeight="Bold" />
</Button>
<Button x:Name="BackspaceButton" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="50" Height="50" Click="BackspaceButton_Click" TabIndex="2">
<TextBlock Text="Õ" FontFamily="Wingdings" FontSize="24" FontWeight="Bold" />
</Button>
</StackPanel>
</Grid>
</Border>

可以使用 Xaml 和转换器进行验证。您所要做的就是;

  • 将绑定与 ErrorTextBlock 一起使用并侦听 PinTextBlock.Text 并通过转换器运行它,这将执行实际验证。

这样,验证逻辑将很好地分离并且是可重用的。还有其他 WPF 内置验证方法,您可以在谷歌上搜索它们。(IDataErrorInfo and ValidationRules)。 这将是"WPF"方式。

但学习曲线并不陡峭。如果你只是想完成这件事,那么是的,把它添加到StackPanel:Button.Click="buttonClickHandler",在代码隐藏中,你将在一个地方接收你点击的每个按钮。并在那里进行计算。

我会有一个字符串,每次单击按钮都会附加到(或在BackspaceClear的情况下进行修改),如果该字符串长度为 4 个字符并且等于 PIN #

如果是 4 个字符且匹配,请移至下一页。如果为 4 个字符且不匹配,则显示错误消息。

我知道这是一个学习应用程序,但如果您将使用 WPF,我强烈建议您学习 MVVM 设计模式。

在这种情况下,我会有一个类似List<KeyValuePair<string, ICommand>> Buttons的东西,它绑定到一个ItemsControlItemsPanelTemplate设置为一个有 3 行和 3 列的UniformGridItemTemplate设置为将内容绑定到Key和命令绑定到ValueButton, 以及一个bool IsErrorDisplayed值,该值在应显示错误消息时设置为 true。

<TextBlock x:Name="ErrorMessageTextBlock" Foreground="Red" 
Visibility="{Binding IsErrorDisplayed, Converter={StaticResource BooleanToVisibiltyConverter}}" 
Grid.ColumnSpan="3" Grid.Row="1" />
<ItemsControl ItemsSource="{Binding Buttons}">
<!-- ItemsPanelTemplate -->
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="3" Rows="3" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<!-- ItemTemplate -->
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Width="50" Height="50" Command="{Binding Value}">
<TextBlock Text="{Binding Key}" FontSize="24" FontWeight="Bold" />
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

我也可能做一些事情来保护 PIN # 所以不会存储为纯文本。

将它们全部关联到同一个事件处理程序。 在这种情况下,使用逻辑将 x:Name 与整数相关联并建立 4 位 PIN。 这只会让你巩固逻辑。

private void one_Click(object sender, RoutedEventArgs e)
{
Button btn = (Button)sender;
Int32 num;
switch (btn.Name)
{
case "one":
num = 1;
break;
case "two":
num = 2;
break;
default:
// problem
}
if (PIN > 1000)   // logic
// now you have you have num and can deal with the logic in one click event;
PIN = (PIN * 10) + num;
if (PIN = correctPIN)
{
}
else
{
}          
}