好的,这让我疯了。我有一个简单的WPF登录应用程序,它有一个登录按钮,如果用户点击键盘上的回车键,我想点击它。这是捕获,我希望按钮看起来像用户点击进入时按下了。
我使用IsDefault = true;然而它会登录,但按钮在处理时永远不会改变。
XAML:
<Button x:Name="SignInButton" Click="SignInButton_Click" Margin="277,523,265,-125" MaxWidth="100" MinWidth="100" IsDefault="False" Style="{StaticResource SignInButton}">
<Button.Effect>
<DropShadowEffect ShadowDepth="6"
BlurRadius="6"
Opacity="1"
Direction="315"
Color="gray" />
</Button.Effect>
<TextBlock x:Name="Connect" TextWrapping="Wrap" Text="Connect" TextAlignment="Center" Padding="0,2,0,0"/>
我甚至试图改变文字:
private void OnKeyDownHandler(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
Connect.Focus();
Connect.Text = "Please Wait...";
SignInButton.IsDefault = true;
}
}
同样,这可行,但文本在按钮处理完毕后才会更改。
答案 0 :(得分:3)
您必须模拟此行为,因为默认情况下,这不是可视更新,只是执行的操作。
这就是我激发视觉更新的方式:
XAML:
<Window x:Class="WpfAnswer001.Window4"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window4" Height="300" Width="300">
<Window.Resources>
<Style x:Key="FocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<SolidColorBrush x:Key="Button.Static.Background" Color="#FFDDDDDD"/>
<SolidColorBrush x:Key="Button.Static.Border" Color="#FF707070"/>
<SolidColorBrush x:Key="Button.MouseOver.Background" Color="#FFBEE6FD"/>
<SolidColorBrush x:Key="Button.MouseOver.Border" Color="#FF3C7FB1"/>
<SolidColorBrush x:Key="Button.Pressed.Background" Color="#FFC4E5F6"/>
<SolidColorBrush x:Key="Button.Pressed.Border" Color="#FF2C628B"/>
<SolidColorBrush x:Key="Button.Disabled.Background" Color="#FFF4F4F4"/>
<SolidColorBrush x:Key="Button.Disabled.Border" Color="#FFADB2B5"/>
<SolidColorBrush x:Key="Button.Disabled.Foreground" Color="#FF838383"/>
<Style x:Key="ButtonStyle1" TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
<Setter Property="Background" Value="{StaticResource Button.Static.Background}"/>
<Setter Property="BorderBrush" Value="{StaticResource Button.Static.Border}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="#FFDDDDDD" SnapsToDevicePixels="true">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.4">
<VisualTransition.GeneratedEasingFunction>
<QuinticEase EasingMode="EaseOut"/>
</VisualTransition.GeneratedEasingFunction>
</VisualTransition>
</VisualStateGroup.Transitions>
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver"/>
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="border">
<EasingColorKeyFrame KeyTime="0" Value="#FFAA3737"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsDefaulted" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.MouseOver.Background}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.MouseOver.Border}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.Disabled.Background}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Disabled.Border}"/>
<Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.Foreground}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top"><Run Text="TextBlock"/></TextBlock>
<TextBox TextWrapping="Wrap" Text="TextBox" Margin="0,0,26,0" Grid.Column="1"/>
<TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" Grid.Row="1"><Run Text="TextBlock"/></TextBlock>
<TextBox TextWrapping="Wrap" Text="TextBox" Margin="0,0,26,0" Grid.Column="1" Grid.Row="1"/>
<Button x:Name="LoginButton" Content="Login" VerticalAlignment="Top" Grid.Row="2" Grid.Column="1" IsDefault="True" Style="{DynamicResource ButtonStyle1}" Click="Button_Click" />
</Grid>
</Window>
代码背后:
using System;
using System.Threading.Tasks;
using System.Windows;
public partial class Window4 : Window
{
public Window4()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
UpdateButtonVisualState();
LoginProcessing();
}
private async Task LoginProcessing()
{
// Simulating a long background task.
await Task.Delay(TimeSpan.FromSeconds(5));
}
private async Task UpdateButtonVisualState()
{
VisualStateManager.GoToState(LoginButton, "Pressed", useTransitions: true);
await Task.Delay(TimeSpan.FromMilliseconds(200));
VisualStateManager.GoToState(LoginButton, "Normal", useTransitions: true);
}
}
无需处理回车键,因为这是默认按钮。
答案 1 :(得分:0)
您可以发布SignInButton_Click
事件处理程序的代码吗?
应该在后台线程上运行它长时间运行的任务,否则在此方法完成并且UI已更新之前,您的按钮不会更改。
答案 2 :(得分:-1)
问题是你正在绑定UI线程。设置Connect.Text =“Please Wait ...”直到UI线程被释放后才会生效,它可以像重绘UI一样工作。您需要显式刷新屏幕,或使用某种异步模式来完成工作。我推荐后者。
有很多关于如何在WPF中进行异步工作的文章。尝试搜索“WPF后台工作者”或“WPF async await”或“WPF Task.Factory.StartNew”这样的术语,只需通过发布这个“相关”链接栏就会显示一些。
编辑:一些链接,显示不同的方法。