简体   繁体   中英

Wpf Event in XAML cannot get the right focus on button

I try to make the button move when I press an arrow key on the keyboard. But what I get is that I always need to press the button with mouse to get the right focus first, and then I can move it with the left arrow key, otherwise not. However, as what I know, the KeyDown event is triggered by the Grid instead of the button.

Here is how I do it in the Code behind:

private void Panel_KeyDown(object sender, KeyEventArgs e)
 {
    Button source = Baffle;
     if (source != null)
     {
        if (e.Key == Key.Left)
          {
             source.Margin = new Thickness(source.Margin.Left - 1, source.Margin.Top,
             source.Margin.Right + 1, source.Margin.Bottom);
            }
        }
 }

The XAML:

<Grid Name="Panel" KeyDown="Panel_KeyDown"  Background="BlanchedAlmond">
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Button Name="Baffle" Template="{StaticResource ButtonTemplate}"   
Grid.Row="1" VerticalAlignment="Bottom" Margin="20" HorizontalAlignment="Center" 
Width="50" Height="20"/>
</Grid>

Could anyone explain this? Thanks.

Interesting ... Not sure why, but if you want to solve it in a simple way you can use this:

public partial class MainWindow : Window
{
    private Button source;
    public MainWindow()
    {
        InitializeComponent();
        source = Baffle;
        source.Focus();
    }

    private void Panel_KeyDown(object sender, KeyEventArgs e)
    {
        if (source != null)
        {
            if (e.Key == Key.Left)
            {
                source.Margin = new Thickness(source.Margin.Left - 1, source.Margin.Top,
                source.Margin.Right + 1, source.Margin.Bottom);
            }
        }
    }
}

(simply give that button the focus on load,and you can move it to your heart content).

That's right - your KEYDOWN event fires only when Grid(Panel) has focus on it. But when your application starts it hasn't focus on it and will get it only when you select any control on Grid for example this button or another one. MainWindow has focus on start so just add this event handler to MainWindow KeyDown.

 <Window x:Class="WpfApplication4.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="Panel_KeyDown">
    <Grid Name="Panel"   Background="BlanchedAlmond">
    .....

This is because Grid by default is not focusable, so the KeyEvent is not going to work until the Grid has focus or one of the controls in the Grid FocusScope has logical focus.

You can set the Grid to Focusable and set the FocusedElement using FocusManager to the Grid and this will work

Example:

<Grid Name="Panel" KeyDown="Panel_KeyDown"  Background="BlanchedAlmond" FocusManager.FocusedElement="{Binding ElementName=Panel}" Focusable="True">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Button Name="Baffle"    
Grid.Row="1" VerticalAlignment="Bottom" Margin="20" HorizontalAlignment="Center" 
Width="50" Height="20"/>
    </Grid>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM