简体   繁体   English

XAML中的Wpf事件无法正确关注按钮

[英]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. 但是,据我所知,KeyDown事件是由网格而不是按钮触发的。

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: 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. 没错-您的KEYDOWN事件仅在Grid(Panel)专注于此事件时才触发。 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. 但是,当您的应用程序启动时,它并不会专注于此,只有在您选择Grid上的任何控件(例如,此按钮或另一个按钮)时,它才会得到它。 MainWindow has focus on start so just add this event handler to MainWindow KeyDown. MainWindow专注于启动,因此只需将此事件处理程序添加到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. 这是因为默认情况下Grid是不可聚焦的,因此KeyEventGrid具有焦点或Grid FocusScope中的控件之一具有逻辑焦点之前将无法工作。

You can set the Grid to Focusable and set the FocusedElement using FocusManager to the Grid and this will work 您可以将Grid设置为Focusable并使用FocusManager将FocusedElement设置为Grid,这将起作用

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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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