How can I prevent input controls from stealing the space character from the TextCompositionManager?

后端 未结 1 437
庸人自扰
庸人自扰 2020-12-19 12:38

Related (but not a dupe!) to this question: Help with the WPF TextCompositionManager events

When using the TextCompositionManager I\'m having an is

相关标签:
1条回答
  • 2020-12-19 13:11

    For the benefit of others, my hacky code.

    My particular app is waiting for a card swipe from a card reader. The following lives in the constructor of the object that watches for a card swipe (this is a side project; most comment cursing edited out):

    // this is where we handle the space and other keys wpf f*s up.
    System.Windows.Input.InputManager.Current.PreNotifyInput += 
        new NotifyInputEventHandler(PreNotifyInput);
    // This is where we handle all the rest of the keys
    TextCompositionManager.AddPreviewTextInputStartHandler(
        Application.Current.MainWindow, 
        PreviewTextInputHandler);
    

    The two methods:

    /// <summary>
    /// Handles the PreNotifyInput event of the input manager.
    /// </summary>
    /// <remarks>Because some controls steal away space (and other) characters, 
    /// we need to intercept the space and record it when capturing.</remarks>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The 
    /// <see cref="System.Windows.Input.NotifyInputEventArgs"/> 
    /// instance containing the event data.</param>
    private void PreNotifyInput(object sender, NotifyInputEventArgs e)
    {
        // I'm only interested in key down events
        if (e.StagingItem.Input.RoutedEvent != Keyboard.KeyDownEvent)
            return;
        var args = e.StagingItem.Input as KeyEventArgs;
        // I only care about the space key being pressed
        // you might have to check for other characters
        if (args == null || args.Key != Key.Space)
            return;
        // stop event processing here
        args.Handled = true;
        // this is my internal method for handling a keystroke
        HanleKeystroke(" ");
    }
    
    
    /// <summary>
    /// This method passes the event to the HandleKeystroke event and turns
    /// off tunneling depending on whether or not Capturing is true.
    /// Also calls StopCapturing when appropriate.
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="e">The 
    /// <see cref="System.Windows.Input.TextCompositionEventArgs"/> 
    /// instance containing the event data.</param>
    private void PreviewTextInputHandler(object sender, 
        TextCompositionEventArgs e)
    {
        HanleKeystroke(e.Text);
    }
    

    When somebody presses a key (or a keystroke is sent to the system) the PreNotifyInput event fires. In this case, I determine if it is a special key (for me I have to worry about the space, but other keys apparently need special attention). If it is a special key, I "handle" the event, stopping all further processing of this keystroke. I then call my internal processing method passing in the space (or whatever special key I just intercepted).

    All other keys are handled by the PreviewTextInputHandler method.

    This code has a lot of stuff stripped out of it. Determining when a swipe event has happened, determining when the swipe has completed, safeguards (timeouts in case I never stop capturing a swipe), etc is removed. How you do this stuff will depend on your code requirements.

    0 讨论(0)
提交回复
热议问题