0

我试图弄清楚如何最好地使用 WPF 的 HandOffBehavior 技术。现在,我的应用程序中有一个滚动错误选框,它动画打开、滚动错误消息,然后自行关闭。

这周我刚刚开始构建这个 WPF 应用程序。问题是我似乎无法优雅地为这样的场景做准备,比如用户在小的连续间隔内点击登录按钮两次或更多次。我希望看到错误字幕仅在用户使用登录按钮提交此类行为而不是多次重复打开和关闭字幕等时继续在屏幕上发送错误文本。这是相关代码。

MainWindow.xaml.cs:

    using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Data.Entity;
using System.Windows.Media.Animation;
using PasswordHash;

namespace ChatClient
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void logIn(object sender, RoutedEventArgs e)
        {
            string nameRecord = "";
            string passRecord = "";

            if (UsernameField.Text == "" || UserPassField.Password == "")
            {
                openErrorMarquee("Username and password required");
            }
            else
            {
                using (otongadgethubEntities logCheck = new otongadgethubEntities())
                {
                    var userNullCheck = logCheck.users.FirstOrDefault(a => a.username == UsernameField.Text);
                    if (userNullCheck == null)
                    {
                        openErrorMarquee("Username does not exist");
                    }

                    if (userNullCheck != null)
                    {
                        nameRecord = userNullCheck.username;
                    }

                    if (nameRecord == UsernameField.Text)
                    {
                        passRecord = Encrypt.MD5(UserPassField.Password).ToLower();
                        if (passRecord == userNullCheck.password)
                        {
                            //Yay! User logged in!
                        }
                        else
                        {
                            openErrorMarquee("Password invalid");
                        }
                    }
                }
            }
        }

        private void openErrorMarquee(string errorMessage)
        {
            errorMarquee.Visibility = System.Windows.Visibility.Visible;

            DoubleAnimation openMarquee = new DoubleAnimation();
            openMarquee.From = 0;
            openMarquee.To = 17;
            openMarquee.Duration = new Duration(TimeSpan.FromSeconds(1.0));
            openMarquee.Completed += (s, doneEvent) => errorMarqueeScroll(errorMessage);
            errorMarquee.BeginAnimation(Rectangle.HeightProperty, openMarquee, HandoffBehavior.Compose);
        }

        private void errorMarqueeScroll(string errorMessage)
        {
            errorText.Text = errorMessage;
            errorText.Visibility = System.Windows.Visibility.Visible;

            double height = errorCanvas.ActualHeight - errorText.ActualHeight;
            errorText.Margin = new Thickness(0, height / 2, 0, 0);
            DoubleAnimation doubleErrorAnimation = new DoubleAnimation();
            doubleErrorAnimation.From = -errorText.ActualWidth;
            doubleErrorAnimation.To = errorCanvas.ActualWidth;

            //doubleErrorAnimation.RepeatBehavior = RepeatBehavior.Forever;
            doubleErrorAnimation.Completed += new EventHandler(closeErrorMarquee);
            doubleErrorAnimation.Duration = new Duration(TimeSpan.FromSeconds(7.0));
            errorText.BeginAnimation(Canvas.RightProperty, doubleErrorAnimation);
        }

        private void closeErrorMarquee(object sender, EventArgs e)
        {
            DoubleAnimation closeMarquee = new DoubleAnimation();
            closeMarquee.From = 17;
            closeMarquee.To = 0;
            closeMarquee.Duration = new Duration(TimeSpan.FromSeconds(1.0));
            closeMarquee.Completed += (s, doneEvent) => {
                errorMarquee.Visibility = System.Windows.Visibility.Hidden;
                errorText.Visibility = System.Windows.Visibility.Hidden;
            };
            errorMarquee.BeginAnimation(Rectangle.HeightProperty, closeMarquee, HandoffBehavior.Compose);
        }
    }
}

对于那些也需要查看窗口的人来说,这里是 XAML:

<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="ChatClient.MainWindow"
        Title="MainWindow" Height="350" Width="525" Icon="media/favicon.gif" Background="#FF3C3636" Foreground="{x:Null}">
    <Window.Resources>
        <Storyboard x:Key="logolayer2excompsoundfad_mp4"/>
    </Window.Resources>
    <Window.BorderBrush>
        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
            <GradientStop Color="Black" Offset="0"/>
            <GradientStop Color="#FF6F6D95" Offset="1"/>
        </LinearGradientBrush>
    </Window.BorderBrush>
    <Window.Triggers>
        <EventTrigger RoutedEvent="FrameworkElement.Loaded">
            <BeginStoryboard Storyboard="{StaticResource logolayer2excompsoundfad_mp4}"/>
        </EventTrigger>
    </Window.Triggers>
    <Grid>
        <Rectangle x:Name="Menu" Fill="#755E5E83" HorizontalAlignment="Left" Height="273" Margin="35,23,0,0" Stroke="Black" VerticalAlignment="Top" Width="446" RadiusY="27.5" RadiusX="27.5"/>
        <Button Content="Log In" HorizontalAlignment="Left" Height="80" Margin="162,200,0,0" Style="{DynamicResource OTonButtonStyle1}" VerticalAlignment="Top" Width="187" FontFamily="Impact" FontSize="26.667" Foreground="#FF1C045B" Click="logIn"/>
        <TextBox x:Name="UsernameField" HorizontalAlignment="Left" Height="25" Margin="204,57,0,0" TextWrapping="Wrap" Text="[Username]" VerticalAlignment="Top" Width="193" Background="#BD251E1E" UseLayoutRounding="False" FontFamily="Copperplate Gothic Light" FontSize="16">
            <TextBox.Foreground>
                <LinearGradientBrush EndPoint="0.5,1" MappingMode="RelativeToBoundingBox" StartPoint="0.5,0">
                    <GradientStop Color="#FF1E2E95" Offset="0.5"/>
                    <GradientStop Color="White" Offset="1"/>
                </LinearGradientBrush>
            </TextBox.Foreground>
        </TextBox>
        <TextBlock HorizontalAlignment="Left" Height="16" Margin="98,57,0,0" TextWrapping="Wrap" Text="Username:" VerticalAlignment="Top" Width="101" FontFamily="Copperplate Gothic Light" FontSize="16">
            <TextBlock.Foreground>
                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                    <GradientStop Color="#FF0A1D5F" Offset="0.374"/>
                    <GradientStop Color="#FF6E7FB9" Offset="1"/>
                </LinearGradientBrush>
            </TextBlock.Foreground>
        </TextBlock>
        <PasswordBox x:Name="UserPassField" HorizontalAlignment="Left" Height="25" Margin="204,99,0,0" VerticalAlignment="Top" Width="193" Background="#BD251E1E" UseLayoutRounding="False" FontFamily="Copperplate Gothic Light" FontSize="16">
            <PasswordBox.Foreground>
                <LinearGradientBrush EndPoint="0.5,1" MappingMode="RelativeToBoundingBox" StartPoint="0.5,0">
                    <GradientStop Color="#FF1E2E95" Offset="0.5"/>
                    <GradientStop Color="White" Offset="1"/>
                </LinearGradientBrush>
            </PasswordBox.Foreground>
        </PasswordBox>
        <TextBlock HorizontalAlignment="Left" Height="16" Margin="98,99,0,0" TextWrapping="Wrap" Text="Password:" VerticalAlignment="Top" Width="101" FontFamily="Copperplate Gothic Light" FontSize="16">
            <TextBlock.Foreground>
                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                    <GradientStop Color="#FF0A1D5F" Offset="0.374"/>
                    <GradientStop Color="#FF6E7FB9" Offset="1"/>
                </LinearGradientBrush>
            </TextBlock.Foreground>
        </TextBlock>
        <Canvas ClipToBounds="True" Name="errorCanvas" Width="446" Height="17" Margin="36,152,35,151">
            <Rectangle x:Name="errorMarquee" Fill="#FF0A0A0C" HorizontalAlignment="Left" Height="17" Stroke="#FF5B1D1D" VerticalAlignment="Top" Width="446" Canvas.Left="-1" Visibility="Hidden"/>
            <TextBlock x:Name="errorText" HorizontalAlignment="Left" Height="16" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Width="690" FontFamily="Copperplate Gothic Bold" FontSize="16" Foreground="#FF7E0202" Visibility="Hidden"/>
        </Canvas>
    </Grid>
</Window>

有人有什么建议吗?

4

2 回答 2

0

你可以只用一个标志来检查这个

private static flag = true;
private void logIn(object sender, RoutedEventArgs e)
    {
        if(flag){
        flag=false;
        string nameRecord = "";
        string passRecord = "";

        if (UsernameField.Text == "" || UserPassField.Password == "")
        {
            openErrorMarquee("Username and password required");
        }
        else
        {
            using (otongadgethubEntities logCheck = new otongadgethubEntities())
            {
                var userNullCheck = logCheck.users.FirstOrDefault(a => a.username == UsernameField.Text);
                if (userNullCheck == null)
                {
                    openErrorMarquee("Username does not exist");
                }

                if (userNullCheck != null)
                {
                    nameRecord = userNullCheck.username;
                }

                if (nameRecord == UsernameField.Text)
                {
                    passRecord = Encrypt.MD5(UserPassField.Password).ToLower();
                    if (passRecord == userNullCheck.password)
                    {
                        //Yay! User logged in!
                    }
                    else
                    {
                        openErrorMarquee("Password invalid");
                    }
                }
            }
        }
      }
      else
      {
      openErrorMarquee("you pressed more one time");
       }
     }
于 2015-11-22T10:17:15.590 回答
0

您可以使用 StopWatch 检查快速点击。在下面给出的代码示例中,尝试缓慢和快速地按下按钮。

    Stopwatch w = new Stopwatch();
    long milliseconds_prev = 0;

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        if (_checkFastClicks())
        {
            Debug.WriteLine("Fast click");
        }
        else
            Debug.WriteLine("Slow click");
    }

    bool _checkFastClicks()
    {
        bool result = false;

        if (!w.IsRunning)
        {
            w.Start();
        }
        if (w.IsRunning)
        {
            if (w.ElapsedMilliseconds - milliseconds_prev < 500)//imp
            {
                if (w.ElapsedMilliseconds > 0)
                {
                    milliseconds_prev = w.ElapsedMilliseconds;
                    result = true;
                }
                else
                    result = false;
            }
            else
            {
                milliseconds_prev = 0;
                w.Reset();
                w.Stop();
                result = false;
            }
        }

        return result;
    }
于 2015-11-22T15:11:28.673 回答