Отключить режим перезаписи в текстовом поле WPF (при нажатии клавиши Insert)

Когда пользователь нажимает клавишу Insert в текстовом поле WPF, элемент управления переключается между режимами вставки и перезаписи. Обычно это визуализируется с помощью другого курсора (линия или блок), но здесь это не так. Поскольку у пользователя нет абсолютно никакой возможности узнать, что режим перезаписи активен, я просто хотел бы полностью отключить его. Когда пользователь нажимает клавишу Insert (или, тем не менее, этот режим может быть активирован намеренно или случайно), TextBox должен просто оставаться в режиме вставки.

Я мог бы добавить какой-нибудь обработчик событий нажатия клавиш и игнорировать все такие события, нажимая клавишу Insert без модификаторов. Будет ли этого достаточно? Вы знаете лучшую альтернативу? В моих представлениях есть несколько элементов управления TextBox, и я не хочу везде добавлять обработчики событий...


person ygoe    schedule 20.08.2013    source источник


Ответы (2)


Вы можете сделать AttachedProperty и использовать предложенный метод ChrisF, таким образом, его легко добавить к TextBoxes, которое вы хотите, в своем приложении.

XAML:

   <TextBox Name="textbox1" local:Extensions.DisableInsert="True" />

Прикрепленное свойство:

public static class Extensions
{
    public static bool GetDisableInsert(DependencyObject obj)
    {
        return (bool)obj.GetValue(DisableInsertProperty);
    }

    public static void SetDisableInsert(DependencyObject obj, bool value)
    {
        obj.SetValue(DisableInsertProperty, value);
    }

    // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty DisableInsertProperty =
        DependencyProperty.RegisterAttached("DisableInsert", typeof(bool), typeof(Extensions), new PropertyMetadata(false, OnDisableInsertChanged));

    private static void OnDisableInsertChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is TextBox && e != null)
        {
            if ((bool)e.NewValue)
            {
                (d as TextBox).PreviewKeyDown += TextBox_PreviewKeyDown;
            }
            else
            {
                (d as TextBox).PreviewKeyDown -= TextBox_PreviewKeyDown;
            }
        }
    }

    static void TextBox_PreviewKeyDown(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Insert && e.KeyboardDevice.Modifiers == ModifierKeys.None)
        {
            e.Handled = true;
        }
    }
person sa_ddam213    schedule 20.08.2013
comment
Спасибо, это работает очень хорошо. Может быть, я мог бы автоматически добавить прикрепленное свойство к каждому TextBox в моем приложении через стиль? - person ygoe; 22.08.2013
comment
Проверять e != null не нужно. - person Dmitri Nesteruk; 06.07.2017

Чтобы избежать добавления обработчиков везде, вы можете создать подкласс TextBox и добавить обработчик событий PreviewKeyDown, который делает то, что вы предлагаете.

В конструкторе:

public MyTextBox()
{
    this.KeyDown += PreviewKeyDownHandler;
}


private void PreviewKeyDownHandler(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Insert)
    {
        e.Handled = true;
    }
}

Однако это означает, что вам нужно будет заменить все варианты использования TextBox на MyTextBox в вашем XAML, поэтому, к сожалению, вам все равно придется редактировать все свои представления.

person ChrisF    schedule 20.08.2013