1

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

我有一个 WPF 应用程序并添加了一个新窗口,该窗口有一个 PIN 键盘、数字 0-9、一个问号按钮(用作帮助按钮)、一个退格按钮(以防您单击了错误的数字)、一个 TextBox顶部显示一个点而不是数字(Wingdings - 字母“l”),以及一个隐藏的 TextBlock,如果没有按正确的顺序输入数字,则会显示不正确的 PIN 消息。目前,我只是硬编码 4 位 PIN(例如 7410),因为我的主要目标是学习如何捕获和验证按钮单击序列。由于我不会使用 Enter 键按钮,因此我想在单击最后一个数字并且顺序正确后立即继续到下一页,否则会显示 PIN 不正确的通知消息。

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

先感谢您。

下面是密码键盘的 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>
4

3 回答 3

1

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

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

这样,验证逻辑将被很好地分离并且可以重用。还有其他 WPF 内置验证方式,您可以在 Google 上搜索它们。(IDataErrorInfo 和 ValidationRules)。这将是“WPF”方式。

但是学习曲线有点陡峭。如果您只想完成这件事,那么可以,将其添加到 StackPanel:Button.Click="buttonClickHandler",然后在代码隐藏中,您将收到您在单个位置单击的每个按钮。并在那里进行计算。

于 2012-09-18T15:16:13.457 回答
1

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

如果是 4 个字符并且匹配,则转到下一页。如果是 4 个字符且不匹配,则显示错误消息。

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

在那种情况下,我会有类似 a 的东西List<KeyValuePair<string, ICommand>> Buttons,它被绑定到一个ItemsControl带有3 行和 3 列的 a 的集合,以及一个将 Content 绑定到 the和 Command 到 the的集合,以及一个得到的值应显示错误消息时设置为 true。ItemsPanelTemplateUniformGridItemTemplateButtonKeyValuebool IsErrorDisplayed

<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 # 所以不会被存储为纯文本。

于 2012-09-18T15:22:51.657 回答
1

将它们全部关联到同一个事件处理程序。在这种情况下,使用逻辑将 x:Name 与 Integer 相关联并建立 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
            {
            }          
        }
于 2012-09-18T15:23:31.333 回答