I'm trying to make a simple keypad for entering a password on a touch monitor. The first touch press on the button highlights it, but doesn't trigger the Command. After the first press, all buttons function normally. When I click the buttons with my mouse they also function normally, even at the first click.
I think it has something to do with focus and I've already set Focusable="False" in the Style, but still the first touch press focusses the button. I would like to disable the focus completely and not have the button highlighted.
My XAML code:
<UserControl x:Class="TestShell.Dialogs.ExitApplicationDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:TestShell.Dialogs"
xmlns:prism="http://prismlibrary.com/"
mc:Ignorable="d"
Background="White"
BorderThickness="2"
d:DesignHeight="400" d:DesignWidth="300">
<UserControl.Resources>
<Style x:Key="TouchButton" TargetType="{x:Type Button}">
<Setter Property="IsTabStop" Value="false"/>
<Setter Property="Focusable" Value="false"/>
<Setter Property="ClickMode" Value="Press"/>
<Setter Property="Margin" Value="3"/>
<Setter Property="FontSize" Value="48"/>
</Style>
</UserControl.Resources>
<prism:Dialog.WindowStyle>
<Style TargetType="Window">
<Setter Property="Height" Value="400" />
<Setter Property="Width" Value="300"/>
<Setter Property="ResizeMode" Value="NoResize" />
<Setter Property="prism:Dialog.WindowStartupLocation" Value="CenterScreen" />
<Setter Property="WindowStyle" Value="None"/>
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="BorderThickness" Value="2"/>
</Style>
</prism:Dialog.WindowStyle>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="100"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Content="{Binding DisplayedPasscode}" Grid.ColumnSpan="3" Margin="10" FontSize="58" BorderBrush="Black" BorderThickness="1" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/>
<Button Grid.Row="1" Grid.Column="0" Content="1" Style="{StaticResource TouchButton}" Command="{Binding KeyPressCommand}" CommandParameter="1"/>
<Button Grid.Row="1" Grid.Column="1" Content="2" Style="{StaticResource TouchButton}" Command="{Binding KeyPressCommand}" CommandParameter="2"/>
<Button Grid.Row="1" Grid.Column="2" Content="3" Style="{StaticResource TouchButton}" Command="{Binding KeyPressCommand}" CommandParameter="3"/>
<Button Grid.Row="2" Grid.Column="0" Content="4" Style="{StaticResource TouchButton}" Command="{Binding KeyPressCommand}" CommandParameter="4"/>
<Button Grid.Row="2" Grid.Column="1" Content="5" Style="{StaticResource TouchButton}" Command="{Binding KeyPressCommand}" CommandParameter="5"/>
<Button Grid.Row="2" Grid.Column="2" Content="6" Style="{StaticResource TouchButton}" Command="{Binding KeyPressCommand}" CommandParameter="6"/>
<Button Grid.Row="3" Grid.Column="0" Content="7" Style="{StaticResource TouchButton}" Command="{Binding KeyPressCommand}" CommandParameter="7"/>
<Button Grid.Row="3" Grid.Column="1" Content="8" Style="{StaticResource TouchButton}" Command="{Binding KeyPressCommand}" CommandParameter="8"/>
<Button Grid.Row="3" Grid.Column="2" Content="9" Style="{StaticResource TouchButton}" Command="{Binding KeyPressCommand}" CommandParameter="9"/>
<Button Grid.Row="4" Grid.Column="1" Content="0" Style="{StaticResource TouchButton}" Command="{Binding KeyPressCommand}" CommandParameter="0"/>
<!--<Button Grid.Row="4" Grid.Column="2" Content="Cancel" Margin="3" FontSize="24" Command="{Binding CancelDialogCommand}"/>
<Button Grid.Row="4" Grid.Column="0" Content="" Margin="3" FontSize="24"/>-->
</Grid>
</UserControl>
I'm using IDialogService.ShowDialog from the Prism library to show the keypad.
Update 1
I tried setting the focus on the Windows hosting the keypad UserControl using the following code, but it made no difference.
public partial class ExitApplicationDialog : UserControl
{
public ExitApplicationDialog()
{
InitializeComponent();
Dispatcher.BeginInvoke(DispatcherPriority.Loaded, new Action(() =>
{
Window yourParentWindow = Window.GetWindow(this);
yourParentWindow.Activate();
yourParentWindow.Focus();
}));
}
}
Update 2
I used Snoop to check where the focus is before and after the first touch press. Snoop indicates that the focus both before and after the first press is on DialogWindow.
Update 3
I'm now thinking about creating a custom button that will also trigger the command on the first press. I've done a test by attaching to the PreviewTouchDown event.
private int index = 0;
private void Button_PreviewTouchDown(object sender, TouchEventArgs e)
{
Debug.WriteLine($"PreviewTouchDown {index}");
index++;
}
The strange thing is that the first time I press the button (when it is not firing the Command), it triggers the event only once, while every other button press triggers the event twice.
Update 4
The difference between touch and mouse click is that the first touch click triggers the PreviewTouchDown and TouchDown events, while every other touch click also triggers de PreviewMouseDown and Click events. With a mouse click the PreviewMouseDown and Click events are always triggered.
| First Touch Press | Following Touch Press |
|---|---|
|
|
| First Mouse Click | Following Mouse Click |
|---|---|
|
|
