我正在努力找出如何最好地使用WPF的HandOffBehavior技术。现在,我在我的应用程序中有一个滚动错误框,它将打开、滚动错误消息,然后关闭自己设置动画。
本周我刚开始构建这个WPF应用程序。问题是,我似乎无法优雅地为用户连续两次或多次单击"登录"按钮这样的场景做好准备。我希望看到错误标记只有在用户使用登录按钮做出这种行为时才继续在屏幕上发送错误文本,而不是多次打开和关闭标记等。以下是相关代码。
主窗口.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>
也许有人有什么建议吗?
您只需使用一个标志即可检查此
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");
}
}
您可以使用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;
}