2

タブ コントロールを持つ Windows フォーム ウィンドウがあり、そのタブの 1 つが子要素として ContentControl を持つ ElementHost をホストしています。このコントロールには、子要素に入力フォーカスがある場合にのみ機能する入力バインディングのコレクションがありますが、フォーカスが失われると反応しなくなります。このような状況で、これらの入力バインディングをより高いレベルで定義することは可能ですか?

4

1 に答える 1

3

1 つの解決策は、Win フォームから WPF ホストに (トンネル) キーボードおよび/またはマウス イベントを渡すことです。以下の概念実証を行いました。機能しますが、制限があり、より多くの作業が必要です。まず、 ElementHostから派生したクラスが必要です。標準のElementHostの代わりに、アプリケーションで使用する必要があります。この新しいカスタム クラスには、WinForms 固有のキーを WPF で使用されるキーにマップする追加メソッドProcessWinFormsKeysが 1 つだけあります。次に、適切な入力バインディングを見つけて実行します。

    public class CustomElementHost : ElementHost
    {
        public void ProcessWinFormsKeys(Keys keys, Keys modifiers)
        {
            var key = KeyInterop.KeyFromVirtualKey((int)keys);

            var modifier = System.Windows.Input.ModifierKeys.None;

            if ((modifiers & Keys.Control) != 0)
                modifier |= System.Windows.Input.ModifierKeys.Control;

            if ((modifiers & Keys.Shift) != 0)
                modifier |= System.Windows.Input.ModifierKeys.Shift;

            if ((modifiers & Keys.Alt) != 0)
                modifier |= System.Windows.Input.ModifierKeys.Alt;

            foreach (InputBinding inputBinding in Child.InputBindings)
            {
                var keyGesture = inputBinding.Gesture as KeyGesture;

                if (keyGesture == null) 
                    continue;

                if(keyGesture.Key == key && keyGesture.Modifiers == modifier)
                    if(inputBinding.Command.CanExecute(inputBinding.CommandParameter))
                        inputBinding.Command.Execute(inputBinding.CommandParameter);
            }
        }
    }

次に、CustomElementHostのインスタンスを含むフォームで、 KeyDownイベントをサブスクライブし、ハンドラー内でProcessWinFormsKeysメソッドを呼び出す必要があります。

    public Form()
    {
        InitializeComponent();

        KeyPreview = true;
        KeyDown += Form_KeyDown;
        ...
    }

    void Form_KeyDown(object sender, KeyEventArgs e)
    {
       elementHost.ProcessWinFormsKeys(e.KeyCode, e.Modifiers);
    }

もう 1 つの解決策は、グローバル ホット キーを利用することです。user32.dll のRegisterHotKey関数を使用する必要があります。ただし、 ElementHostで動作するかどうかはわかりません。試してみたい場合は、stackoverflow に関するいくつかの質問とインターネットの多数の記事があります。

于 2014-09-09T11:53:23.760 に答える