我正在使用ChromiumWebBrowser
库提供的CefSharp
向我的C#应用程序的用户显示一个网站。
我正在尝试添加功能以允许用户放大/缩小'使用键盘快捷键,即CTRL +
/ CTRL -
。
我已设法使用&{39;低级全局键盘挂钩/接收器在嵌入式浏览器中添加KeyboardListener
:http://www.dylansweb.com/2014/10/low-level-global-keyboard-hook-sink-in-c-net/
目前,我的应用程序将放大'在浏览器上,当浏览器处于焦点位置时,用户按下' +'在键盘上。我使用以下方式完成了这项工作:
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();
}
}
}
我使用浏览器在我的XAML中显示的<KeyBinding>
上的<Grid>
标记来调用此方法:
<KeyBinding Modifiers="Ctrl" Key="LeftCtrl" Command="{Binding _listener_OnKeyPressed}"></KeyBinding>
但我遇到的问题是:虽然应用程序检测到&#39; CTRL&#39;按下键(调试被写入控制台),似乎它无法检测第二个键上的按键(&#39; +&#39;键)。
我尝试添加第二个侦听器,只在leftCtrlDown
或rightCtrlDown
布尔值为真时(即当用户按任意一个CTRL键时)在第一个侦听器内调用,但是该应用程序似乎仍然没有检测到按下第二个键...
如何让我的应用程序“倾听”#39;按下另一个键,虽然它已经确认当前正在按下一个键?
修改
我尝试过做答案中的建议,现在已经在我的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" />
说:
名称&#34;缩放&#34;命名空间中不存在&#34; clr-namespace:Agent&#34;。
即使它显然也是如此。
答案 0 :(得分:6)
此行不起作用:
/^[a-zA-Z0-9#.,;:'()\/&\-"!]+( [a-zA-Z0-9#.,;:'()\/&\-"!]+)*$/
<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>
通常你会使用Commanding在代码中定义Command并在XAML中使用它。将该命令绑定到private void SimpleCommand_OnExecuted(object sender, object e)
{
MessageBox.Show("SimpleCommand Executed");
}
,KeyBinding
或Button
(或其他内容)时,您的实现的MenuItem
方法可用于禁用该命令(因此禁用它所绑定的元素。
答案 1 :(得分:1)
问题是你只是挂钩了WM_KEYDOWN和WM_SYSKEYDOWN消息。您还需要挂钩WM_KEYUP和WM_SYSKEYUP消息。为了确定当前是否按下了CTRL键,您必须在按下键时将leftCtrlDown设置为true,并在释放键时设置leftCtrlDown = false。当你按下除控件之外的任何键时,你的代码设置leftCtrlDown = false。这种逻辑是不正确的。
查看链接的文章,您需要修改HookCallback()以侦听WM_KEYUP和WM_SYSKEYUP。然后,您将需要为key up添加另一个事件,或者在KeyPressedArgs中添加一个标志,以指示是否正在为key up或key down触发事件。无论哪种方式。