如何禁用按钮的回车键
How to disable Enter Key for a Button
我有一个绑定了命令的按钮以及 F1 键的键绑定。当焦点位于该按钮上时,Enter 键也会触发我不想要的命令。我希望按钮仅在 F1 和鼠标单击时触发。如何禁用此 Enter 键?
<Button Name="TestButton" Content="Run (F1)" Margin="10,4" Width="100" FontSize="16" Command="{Binding TestRunCommand}">
<Button.Style>
<Style TargetType="Button" BasedOn="{StaticResource ResourceKey=BlackButton}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsEnabled,ElementName=TestButton}" Value="True">
<Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName=TestButton}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
我的按键绑定如下:
<UserControl.InputBindings>
<KeyBinding Key="F1" Command="{Binding Path=TestViewModel.TestRunCommand}"/>
</UserControl.InputBindings>
当我移除焦点触发器时,F1 键也不起作用。所以,我有这个 Setter
属性 for F1 键来工作。
只需从 <Button ...>
中删除 Command="{Binding TestRunCommand}"
,按钮在按下时将不会执行任何操作。
这是一个最小的完整示例:
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
<local:DC/>
</Window.DataContext>
<Window.InputBindings>
<KeyBinding Key="F1" Command="{Binding Path=F1Command}"/>
</Window.InputBindings>
<StackPanel>
<Button Name="TestButton" Content="Run (F1)" Margin="10,4" Width="100" FontSize="16"
Command="{Binding TestRunCommand}">
<!-- ^- remove this if you want it to do nothing -->
<Button.Style>
<Style TargetType="Button" >
<Style.Triggers>
<DataTrigger Binding="{Binding IsEnabled,ElementName=TestButton}" Value="True">
<Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName=TestButton}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</StackPanel>
</Window>
以及后面的代码:
public class DC
{
public ICommand TestRunCommand
{
get { return new CommandHandler(() => MessageBox.Show("Enter / Space / Click"), () => true); }
}
public ICommand F1Command
{
get { return new CommandHandler(() => MessageBox.Show("F1"), () => true); }
}
}
public class CommandHandler : ICommand
{
private readonly Action _action;
private readonly Func<bool> _canExecute;
public CommandHandler(Action action, Func<bool> canExecute)
{
_action = action;
_canExecute = canExecute;
}
public event EventHandler CanExecuteChanged
{
add => CommandManager.RequerySuggested += value;
remove => CommandManager.RequerySuggested -= value;
}
public bool CanExecute(object parameter) => _canExecute.Invoke();
public void Execute(object parameter) => _action();
}
您可以为 PreviewKeyDown
事件附加事件处理程序:
<Button Name="TestButton" Content="Run (F1)" Margin="10,4" Width="100" FontSize="16" Command="{Binding TestRunCommand}" PreviewKeyDown="OnPreviewKeyDown">
在事件处理程序中,检查 Enter 键并处理事件。
private void OnPreviewKeyDown(object sender, KeyEventArgs e)
{
e.Handled = (e.Key == Key.Enter || e.Key == key.Return);
}
一个稍微更有创意的变体是创建一个什么都不做的 ICommand
。它将作为 KeyBinding
绑定到 Enter 键,从而阻止原始命令。为了方便使用,我创建了一个标记扩展。
public class IgnoreCommandExtension : MarkupExtension
{
private static readonly IgnoreCommand IgnoreCommandInstance = new IgnoreCommand();
private class IgnoreCommand : ICommand
{
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
}
public event EventHandler CanExecuteChanged;
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return IgnoreCommandInstance;
}
}
<Button Name="TestButton" Content="Run (F1)" Margin="10,4" Width="100" FontSize="16" Command="{Binding TestRunCommand}">
<Button.InputBindings>
<KeyBinding Key="Enter" Command="{local:IgnoreCommand}"/>
<KeyBinding Key="Return" Command="{local:IgnoreCommand}"/>
</Button.InputBindings>
<!-- ...other code. -->
</Button>
我终于想出了一个简单的方法来阻止输入键,方法是添加 KeyboardNavigation.AcceptsReturn="False"
。
<Button Name="TestButton" Content="Run (F1)" Margin="10,4" Width="100" FontSize="16" Command="{Binding TestRunCommand}" KeyboardNavigation.AcceptsReturn="False">
这有效。
我有一个绑定了命令的按钮以及 F1 键的键绑定。当焦点位于该按钮上时,Enter 键也会触发我不想要的命令。我希望按钮仅在 F1 和鼠标单击时触发。如何禁用此 Enter 键?
<Button Name="TestButton" Content="Run (F1)" Margin="10,4" Width="100" FontSize="16" Command="{Binding TestRunCommand}">
<Button.Style>
<Style TargetType="Button" BasedOn="{StaticResource ResourceKey=BlackButton}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsEnabled,ElementName=TestButton}" Value="True">
<Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName=TestButton}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
我的按键绑定如下:
<UserControl.InputBindings>
<KeyBinding Key="F1" Command="{Binding Path=TestViewModel.TestRunCommand}"/>
</UserControl.InputBindings>
当我移除焦点触发器时,F1 键也不起作用。所以,我有这个 Setter
属性 for F1 键来工作。
只需从 <Button ...>
中删除 Command="{Binding TestRunCommand}"
,按钮在按下时将不会执行任何操作。
这是一个最小的完整示例:
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
<local:DC/>
</Window.DataContext>
<Window.InputBindings>
<KeyBinding Key="F1" Command="{Binding Path=F1Command}"/>
</Window.InputBindings>
<StackPanel>
<Button Name="TestButton" Content="Run (F1)" Margin="10,4" Width="100" FontSize="16"
Command="{Binding TestRunCommand}">
<!-- ^- remove this if you want it to do nothing -->
<Button.Style>
<Style TargetType="Button" >
<Style.Triggers>
<DataTrigger Binding="{Binding IsEnabled,ElementName=TestButton}" Value="True">
<Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName=TestButton}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</StackPanel>
</Window>
以及后面的代码:
public class DC
{
public ICommand TestRunCommand
{
get { return new CommandHandler(() => MessageBox.Show("Enter / Space / Click"), () => true); }
}
public ICommand F1Command
{
get { return new CommandHandler(() => MessageBox.Show("F1"), () => true); }
}
}
public class CommandHandler : ICommand
{
private readonly Action _action;
private readonly Func<bool> _canExecute;
public CommandHandler(Action action, Func<bool> canExecute)
{
_action = action;
_canExecute = canExecute;
}
public event EventHandler CanExecuteChanged
{
add => CommandManager.RequerySuggested += value;
remove => CommandManager.RequerySuggested -= value;
}
public bool CanExecute(object parameter) => _canExecute.Invoke();
public void Execute(object parameter) => _action();
}
您可以为 PreviewKeyDown
事件附加事件处理程序:
<Button Name="TestButton" Content="Run (F1)" Margin="10,4" Width="100" FontSize="16" Command="{Binding TestRunCommand}" PreviewKeyDown="OnPreviewKeyDown">
在事件处理程序中,检查 Enter 键并处理事件。
private void OnPreviewKeyDown(object sender, KeyEventArgs e)
{
e.Handled = (e.Key == Key.Enter || e.Key == key.Return);
}
一个稍微更有创意的变体是创建一个什么都不做的 ICommand
。它将作为 KeyBinding
绑定到 Enter 键,从而阻止原始命令。为了方便使用,我创建了一个标记扩展。
public class IgnoreCommandExtension : MarkupExtension
{
private static readonly IgnoreCommand IgnoreCommandInstance = new IgnoreCommand();
private class IgnoreCommand : ICommand
{
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
}
public event EventHandler CanExecuteChanged;
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return IgnoreCommandInstance;
}
}
<Button Name="TestButton" Content="Run (F1)" Margin="10,4" Width="100" FontSize="16" Command="{Binding TestRunCommand}">
<Button.InputBindings>
<KeyBinding Key="Enter" Command="{local:IgnoreCommand}"/>
<KeyBinding Key="Return" Command="{local:IgnoreCommand}"/>
</Button.InputBindings>
<!-- ...other code. -->
</Button>
我终于想出了一个简单的方法来阻止输入键,方法是添加 KeyboardNavigation.AcceptsReturn="False"
。
<Button Name="TestButton" Content="Run (F1)" Margin="10,4" Width="100" FontSize="16" Command="{Binding TestRunCommand}" KeyboardNavigation.AcceptsReturn="False">
这有效。