簡體   English   中英

C#WPF在XAML中添加KeyBinding事件

[英]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”鍵(將調試寫入控制台),但是似乎無法檢測到第二個鍵的按下( “ +”鍵)。

我嘗試添加第二個偵聽器,僅當leftCtrlDownrightCtrlDown布爾值中的任何一個為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中使用它。 當您將該命令綁定到KeyBindingButtonMenuItem (或其他)時,實現的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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM