Search code examples
c#wpfkeyboard-events

How to make keyboardevent common to other files in C# WPF?


I have a PreviewKeyDown event in my code like below:

    private void Box_PreviewKeyDown(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Space)
        {
            e.Handled = true;
        }
        if ((e.Key == Key.V) && (e.KeyboardDevice.Modifiers & ModifierKeys.Control) != 0)
        {
            e.Handled = true;
        }
        else
        {
            base.OnKeyDown(e);
        }
    }

This code runs blocking Ctrl+V and space key in TextBox or PasswordBox control in wpf.

What I want to do is making this code as common and call this code in PasswordBox in another file.

Any solution? I know I can allocate PreviewKeyDown event to each control but it is repeated so I want to avoid duplication.


Solution

  • One option would be to wrap the functionality in a reusable attached behaviour:

    public static class Behavior
    {
        public static bool GetHandlePreviewKeyDown(UIElement element) =>
            (bool)element.GetValue(HandlePreviewKeyDownProperty);
    
        public static void SetHandlePreviewKeyDown(UIElement element, bool value) =>
            element.SetValue(HandlePreviewKeyDownProperty, value);
    
        public static readonly DependencyProperty HandlePreviewKeyDownProperty =
            DependencyProperty.RegisterAttached(
            "HandlePreviewKeyDown",
            typeof(bool),
            typeof(Behavior),
            new UIPropertyMetadata(false, OnChanged));
    
        private static void OnChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            UIElement element = (UIElement)d;
            bool value = (bool)e.NewValue;
            if (value)
                element.PreviewKeyDown += Element_PreviewKeyDown;
            else
                element.PreviewKeyDown -= Element_PreviewKeyDown;
        }
    
        private static void Element_PreviewKeyDown(object sender, KeyEventArgs e) =>
            e.Handled = (e.Key == Key.Space) || ((e.Key == Key.V) && (e.KeyboardDevice.Modifiers & ModifierKeys.Control) != 0);
    }
    

    Usage:

    <TextBox local:Behavior.HandlePreviewKeyDown="true" />