WPF Enter key press How to make a button pressed

Okay, this is driving me crazy. I have a simple WPF login application that has a login button that I want to click if the user presses the enter key on the keyboard. Here is a trick, I want the button to look like it was pressed when the user logs in.

I am using IsDefault = true; and it will log in, however the button never changes as it is processed.

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"/>

      

I even tried to just change the text:

    private void OnKeyDownHandler(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Enter)
        {
            Connect.Focus();

            Connect.Text = "Please Wait...";

            SignInButton.IsDefault = true;

        }
    }

      

Again, this works, but the text doesn't change until the button processes.

+3


source to share


3 answers


You will have to simulate this behavior as by default this is not visually updated, only the actions performed.

This is how I do the visual update:

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>

      



Code behind:

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);
    }
}

      

You don't need to handle the enter key as this is the default button.

+3


source


Can you post the code for your event handler SignInButton_Click

?



A multitasking task must be running on a background thread, otherwise your button won't change until this method completes and the user interface has not been updated.

0


source


The problem is you are binding the UI thread. Setting Connect.Text = "Please Wait ..." does not take effect until the UI thread is released and it can act as a UI redraw. You either need to explicitly update the screen or use some asynchronous pattern to work. I recommend the latter.

There are many articles on how to do asynchronous work in WPF. Try searching for terms like "WPF background worker" or "WPF async await" or "WPF Task.Factory.StartNew", it's easy by posting this link on the appropriate link line on the side.

Edit: some links for you showing different approaches.

WPF blocking attempt asynchronously

How do I update a WPF control from a TPL task?

-1


source







All Articles