【问题标题】:Key combination shortcut组合键快捷键
【发布时间】:2018-01-03 01:01:03
【问题描述】:

我正在创建一个 WPF 应用程序并且我有三个窗口 (MainWindow, SecondWindow and CameraWindow)。我添加了快捷方式("m") 将相机设置为图像模式。当CameraWindow 处于活动状态时,这可以正常工作。

private void Window_KeyDown(object sender, KeyEventArgs e)
{
    var key = e.Key.ToString().ToLower();
    if (key.Contains("m"))
    {              
       camera.SetImageMode();                
    }
}

我正在寻找在我的应用程序中将相机设置为图像模式的方法。我的意思是我应该能够从任何地方将相机设置为图像模式,即使 CameraWindow 未处于活动状态。

Ctrl+M 可以是组合键。

欢迎提出任何建议!

【问题讨论】:

  • 如果您想遵守 MVVM,您可能需要分别在您的视图模型和视图上使用 ICommands 和 CommandBinding 引用。在您的情况下,您可能希望在您的Window.InputBindings 上添加一个KeyBinding
  • @Adwaenyth 感谢您的评论。您能否向我展示/链接一个这样做的示例,因为我是 wpf 的新手...
  • 取决于你知道多少,或者说你还不知道多少,这可能会很长。但是你可能想开始here

标签: c# wpf keyboard-shortcuts


【解决方案1】:
public class KeyboardHandler : IDisposable
    {
        private readonly int _modKey;
        private const int WmHotkey = 0x0312;
        private readonly WindowInteropHelper _host;

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vlc);

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool UnregisterHotKey(IntPtr hWnd, int id);


        private readonly ISubject<Unit> _hotKeyHandleSubject = new Subject<Unit>();
        public IObservable<Unit> WhenHotKeyHandled { get { return _hotKeyHandleSubject.AsObservable(); } }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="mainWindow">the handle to the main window</param>
        /// <param name="vkKey">the virtual key you need to press -> https://msdn.microsoft.com/en-us/library/ms927178.aspx </param>
        /// <param name="modKey">the modifier key you need to press (2 is CTRL by Default) -> https://msdn.microsoft.com/it-it/library/windows/desktop/ms646279(v=vs.85).aspx </param>
        public KeyboardHandler(Window mainWindow, int vkKey, int modKey = 2)
        {
            _modKey = modKey;
            _host = new WindowInteropHelper(mainWindow);

            SetupHotKey(_host.Handle, vkKey);
            ComponentDispatcher.ThreadPreprocessMessage += ComponentDispatcher_ThreadPreprocessMessage;
        }

        private void ComponentDispatcher_ThreadPreprocessMessage(ref MSG msg, ref bool handled)
        {
            if (msg.message == WmHotkey)
            {
                _hotKeyHandleSubject.OnNext(Unit.Default);
            }
        }

        private void SetupHotKey(IntPtr handle, int vkKey)
        {
            RegisterHotKey(handle, GetType().GetHashCode(), _modKey, vkKey);
        }

        public void Dispose()
        {
            ComponentDispatcher.ThreadPreprocessMessage -= ComponentDispatcher_ThreadPreprocessMessage;
            UnregisterHotKey(_host.Handle, GetType().GetHashCode());
        }
    }

像这样使用它:

_keyboardHandler = new KeyboardHandler(this, 0x4D);
            _disposable = _keyboardHandler.WhenHotKeyHandled.ObserveOn(SynchronizationContext.Current).Subscribe(_ =>
            {
                TextBlock.Text += new Random().Next(10) + "_";
            });

感谢https://stackoverflow.com/a/1960122/2159837,我只是稍微修改了一下

如果您的应用程序没有焦点,这也有效

【讨论】:

    【解决方案2】:

    经过长时间的搜索和实验,终于找到了解决方案 https://stackoverflow.com/a/12676910/8152725

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-10
      • 1970-01-01
      相关资源
      最近更新 更多