[英]C# WPF add KeyBinding events in XAML
我正在使用CefSharp
库提供的ChromiumWebBrowser
向我的C#应用程序的用户显示一个网站。
我正在尝试添加功能,以允许用户使用键盘快捷键(即CTRL +
/ CTRL -
“放大/缩小”。
我设法使用“低级全局键盘挂钩/接收器”向嵌入式浏览器添加了一个KeyboardListener
,该网址位于: http : //www.dylansweb.com/2014/10/low-level-global-keyboard-hook-sink-网络内/
目前,当浏览器处于“焦点对准”状态,并且用户按下键盘上的“ +”时,我的应用程序将在浏览器中“放大”。 我使用以下方法完成此操作:
private void _listener_OnKeyPressed(object sender, KeyPressedArgs e)
{
if(e.KeyPressed == Key.Add)
{
zoomInExecuted();
}
}
我真正想要的只是在用户按住“ CTRL”键的同时按下“ +”键时才允许放大。
我在C#中编写了以下方法(此方法称为:
private void _listener_OnKeyPressed(object sender, KeyPressedArgs e)
{
Debug.WriteLine("e: " + e.KeyPressed.ToString());
if(e.KeyPressed == Key.LeftCtrl)
{
leftCtrlDown = true;
Debug.WriteLine("LeftCtrl pressed, leftCtrlDown should be true: ", leftCtrlDown.ToString());
}
else
{
leftCtrlDown = false;
}
if(e.KeyPressed == Key.RightCtrl)
{
rightCtrlDown = true;
Debug.WriteLine("RightCtrl pressed, rightCtrlDown should be true: ", rightCtrlDown.ToString());
}
else
{
rightCtrlDown = false;
}
if((leftCtrlDown == true)) //&& (e.KeyPressed == Key.Add))
{
if (e.KeyPressed == Key.Add)
{
Debug.WriteLine("Ctrl & + pressed, 'zoomInExecuted()' should be called ");
zoomInExecuted();
}
}else if((rightCtrlDown == true)) //&& (e.KeyPressed == Key.Add))
{
if (e.KeyPressed == Key.Add)
{
Debug.WriteLine("rightCtrl & + pressed, 'zoomInExecuted()' should be called ");
zoomInExecuted();
}
}
}
我使用<Grid>
上的<KeyBinding>
标记调用此方法,浏览器在其中显示在我的XAML中:
<KeyBinding Modifiers="Ctrl" Key="LeftCtrl" Command="{Binding _listener_OnKeyPressed}"></KeyBinding>
但是我遇到的问题是:尽管应用程序检测到何时按下了“ CTRL”键(将调试写入控制台),但是似乎无法检测到第二个键的按下( “ +”键)。
我尝试添加第二个侦听器,仅当leftCtrlDown
或rightCtrlDown
布尔值中的任何一个为true时(即,当用户按下任一CTRL键时),才在第一个侦听器中调用它,但是应用程序似乎仍然无法检测到按动第二把钥匙
在已经确认当前正在按下一个键的同时,如何使我的应用“监听”另一个键?
编辑
我尝试做答案中建议的操作,现在在我的XAML中使用:
<Window x:Class="..."
....
xmlns:local="clr-namespace:Agent"
... >
<Window.Resources>
...
</Window.Resources>
<Grid Name="grid">
...
<Grid x:Name="grdBrowserHost" MinHeight="900" Height="Auto" MinWidth="1205" Width="Auto" Margin="5,0,0,0" DockPanel.Dock="Bottom" Grid.ColumnSpan="1" >
<Grid.InputBindings>
<KeyBinding Modifiers="Ctrl" Key="Add" Command="{Binding _listener_OnKeyPressed}"></KeyBinding>
</Grid.InputBindings>
...
<cefSharp:ChromiumWebBrowser Name="browser" ...>
<KeyBinding Modifiers="Ctrl" Key="Add">
<KeyBinding.Command>
<local:Zoom Executed="zoomInExecuted" />
</KeyBinding.Command>
</KeyBinding>
</cefSharp:ChromiumWebBrowser.InputBindings>
</Grid>
</Grid>
...
</Window>
我添加的Zoom.cs
类如下:
namespace Agent
{
class Zoom : ICommand
{
public event EventHandler<object> Executed;
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
if (Executed != null)
Executed(this, parameter);
}
public event EventHandler CanExecuteChanged;
}
}
但是由于某种原因,我在XAML上遇到了一个编译错误:
<local:Zoom Executed="zoomInExecuted" />
其中说:
名称“ Zoom”在名称空间“ clr-namespace:Agent”中不存在。
即使很明显。
该行不起作用:
<KeyBinding Modifiers="Ctrl" Key="LeftCtrl" Command="{Binding _listener_OnKeyPressed}"/>
KeyBinding.Command
需要一个实现ICommand
的对象,您将其绑定到方法。
ICommand
接口的基本实现如下所示:
class SimpleCommand : ICommand
{
public event EventHandler<object> Executed;
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
if (Executed != null)
Executed(this, parameter);
}
public event EventHandler CanExecuteChanged;
}
您可以这样使用:
<Window.InputBindings>
<KeyBinding Modifiers="Control" Key="Add">
<KeyBinding.Command>
<local:SimpleCommand Executed="SimpleCommand_OnExecuted"/>
</KeyBinding.Command>
</KeyBinding>
</Window.InputBindings>
并在后面的代码中:
private void SimpleCommand_OnExecuted(object sender, object e)
{
MessageBox.Show("SimpleCommand Executed");
}
通常,您将使用Commanding在代码中定义Command并在XAML中使用它。 当您将该命令绑定到KeyBinding
, Button
或MenuItem
(或其他)时,实现的CanExecute
方法可用于禁用命令(并因此禁用其绑定的Element)。
问题是您只钩住WM_KEYDOWN和WM_SYSKEYDOWN消息。 您还需要挂钩WM_KEYUP和WM_SYSKEYUP消息。 为了确定当前是否按下了CTRL键,您必须在按下键时将leftCtrlDown = true设置,并在释放键时将leftCtrlDown = false设置。 当您按下控件以外的任何键时,您的代码设置leftCtrlDown = false。 这种逻辑是不正确的。
查看链接的文章,您将需要修改HookCallback()来侦听WM_KEYUP和WM_SYSKEYUP。 然后,您将需要添加另一个事件以进行按键激活,或者在FlagPressedArgs中添加一个标志以指示该事件是针对按键激活还是按键按下而触发的。 无论哪种方式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.