Reputation: 1325
I'm trying to receive key strokes in a Window (Not a Form). I receive event, until a button is pressed. After that no matter what I do, the key down event doesn't fire anymore. Is there any solution? I have searched for it, seems like every one is suggesting a solution using
this.KeyPreview = true;
but this can't work here, as Window doesn't have such an attribute. Helps much appreciated. I have already set all the children Focusable to False, and Window is set to be focusable. But this hasn't helped.
The XAML is
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="463" Width="726" AllowsTransparency="False" PreviewKeyDown="Window_PreviewKeyDown" KeyDown="Window_KeyDown_1" WindowStartupLocation="CenterScreen" Focusable="True">
<Window.Background>
<RadialGradientBrush>
<GradientStop Color="#FF3EB5FF" Offset="1" />
<GradientStop Color="White" Offset="0" />
</RadialGradientBrush>
</Window.Background>
<Grid Name="grid1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="434*" />
<ColumnDefinition Width="270*" />
</Grid.ColumnDefinitions>
<Grid Margin="10,10,0,12" Name="EquiGrid" Focusable="False">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="198*" />
</Grid.ColumnDefinitions>
<Image Grid.ColumnSpan="2" Name="EquiImage" Stretch="Uniform" Margin="0,0,0,6" />
<Grid Grid.Column="1" Height="100" HorizontalAlignment="Left" Margin="489,90,0,0" Name="grid2" VerticalAlignment="Top" Width="200" />
</Grid>
<Label Content="Label" Height="28" Margin="14,12,12,0" Name="longLabel" VerticalAlignment="Top" Grid.Column="1" OpacityMask="White" BorderBrush="Red" Focusable="False">
<Label.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="White" Offset="0.025" />
<GradientStop Color="#FFDBDBDB" Offset="1" />
</LinearGradientBrush>
</Label.Background>
</Label>
<Label Content="Label" Height="28" Margin="14,46,12,0" Name="latLabel" VerticalAlignment="Top" Grid.Column="1" Focusable="False">
<Label.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="White" Offset="0.025" />
<GradientStop Color="#FFDBDBDB" Offset="1" />
</LinearGradientBrush>
</Label.Background>
</Label>
<TextBlock Margin="14,80,12,54" Name="descriptionText" Padding="10" Text="" Grid.Column="1" Focusable="False"><TextBlock.Background><LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"><GradientStop Color="White" Offset="0.025" /><GradientStop Color="#FFDBDBDB" Offset="1" /></LinearGradientBrush></TextBlock.Background></TextBlock>
<Button Content="Load Image" Grid.Column="1" Margin="14,0,0,12" Name="button1" Height="36" VerticalAlignment="Bottom" HorizontalAlignment="Left" Width="124" Click="button1_Click" Focusable="False" />
<Button Content="Load XML" Grid.Column="1" Margin="0,0,12,12" Name="button2" Height="36" VerticalAlignment="Bottom" HorizontalAlignment="Right" Width="114" Click="button2_Click" Focusable="False" />
</Grid>
</Window>
and the handler:
private void Window_KeyDown_1(object sender, System.Windows.Input.KeyEventArgs e)
{
Console.WriteLine("k");
}
I have also found out that the problem is in the focus. The children, although set to be not focusable, steal the focus on the window and stop the event firing.
Upvotes: 9
Views: 19542
Reputation: 177
Because I encountered a similar issue, I contribute by sharing my solution.
Author said : "I have also found out that the problem is in the focus".
And it's also what I discovered wen I removed the Maximized
property to my Window ; my content was undersized and it was more obvious to watch the reaction to Up
/Down
/Left
/Right
KeyDown event : the content inside my scrollviewer was moving.
So in my situation a simple Focusable=false
on Scrollviewer resolved it.
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" Focusable="False"
MouseDown="ScrollViewer_MouseDown" MouseUp="ScrollViewer_MouseUp" MouseMove="ScrollViewer_MouseMove">
<!-- A very interesting content -->
</ScrollViewer>
It was a loss of time because the KeyDown event is handled by default and even when it is not necessary so it wasn't possible to watch any effect. Changing the uses cases of my window was the path to my solution. I hope it can helps.
Upvotes: 1
Reputation: 4891
You need to implement global events in WPF. This works no matter what control is currently in focus or selected.
https://blog.magnusmontin.net/2015/03/31/implementing-global-hot-keys-in-wpf/
Upvotes: 1
Reputation: 11734
Try using the KeyDown event.
In codebehind
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_KeyDown(object sender, KeyEventArgs e)
{
System.Diagnostics.Debug.WriteLine("KeyDown");
System.Diagnostics.Debug.WriteLine(e.Key);
}
private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
{
System.Diagnostics.Debug.WriteLine("PreviewKeyDown");
System.Diagnostics.Debug.WriteLine(e.Key);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("Button clicked");
}
}
XAML
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" KeyDown="Window_KeyDown" PreviewKeyDown="Window_PreviewKeyDown">
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<TextBox Grid.Row="0"></TextBox>
<Button Grid.Row="1" Content="Click me!" Click="Button_Click"></Button>
</Grid>
</Window>
Upvotes: 3