C#WPF在XAML

时间:2016-06-09 09:52:42

标签: c# wpf xaml keyboard-shortcuts keypress

我正在使用ChromiumWebBrowser库提供的CefSharp向我的C#应用​​程序的用户显示一个网站。

我正在尝试添加功能以允许用户放大/缩小'使用键盘快捷键,即CTRL + / CTRL -

我已设法使用&{39;低级全局键盘挂钩/接收器在嵌入式浏览器中添加KeyboardListenerhttp://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;键)。

我尝试添加第二个侦听器,只在leftCtrlDownrightCtrlDown布尔值为真时(即当用户按任意一个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;。

即使它显然也是如此。

2 个答案:

答案 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"); } KeyBindingButton(或其他内容)时,您的实现的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触发事件。无论哪种方式。