Предотвратить пузыри события KeyDown из TextBox в MainWindow в WPF - PullRequest
1 голос
/ 03 ноября 2011

У меня есть программа, которая содержит текстовое поле управления.Пользователь может вводить текст в этот элемент управления.Пользователь также может нажимать определенные клавиши для запуска других действий (это обрабатывается в главном окне).У меня есть пример кода XAML и C # для демонстрации моей установки.

XAML

<Window x:Class="RoutedEventBubbling.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>

        <TextBox Grid.Row="0" />
        <TextBox x:Name="Output" Grid.Row="1" IsReadOnly="True" />
    </Grid>
</Window>

C #

using System.Windows;
using System.Windows.Input;

namespace RoutedEventBubbling
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private int mHitCount = 0;

        public MainWindow()
        {
            InitializeComponent();
        }

        protected override void OnKeyDown(KeyEventArgs e)
        {
            base.OnKeyDown(e);

            this.Output.Text = string.Format("Hit Count: {0}", ++mHitCount);
        }
    }
}

Как вы, возможно, поняли, в случае этой программы, если я начну вводить первый TextBox, второй будет обновляться с количеством посещений.Это нежелательный результат, поскольку у меня могут быть определенные действия, которые я хочу вызвать при обработке метода OnKeyDown в MainWindow.

Таким образом, мой вопрос таков: возможно ли предотвратить использование метода OnKeyDownвызывается в главном окне, все еще позволяя вводить текст в текстовое поле?Мне известен подход e.Handled = true, но в этом случае выполнение этого при событии KeyDown в TextBox предотвратит ввод текста.Если это невозможно, мне придется найти другой способ справиться со всем этим.

Заранее спасибо.

РЕДАКТИРОВАТЬ

У меня естьтолько что нашел способ решить эту проблему.Если вместо этого я обработаю метод MainWindow OnTextInput, то желаемый результат будет достигнут, поскольку будет обработано событие TextInput TextBox.Ниже приведен пример кода, который я использовал:

private Key mPressedKey;

protected override void OnKeyDown(KeyEventArgs e)
{
    // Note: This method will be called first.

    base.OnKeyDown(e);

    // Store the pressed key
    mPressedKey = e.Key;
}

protected override void OnTextInput(TextCompositionEventArgs e)
{
    // Note: This method will be called second, and only if the textbox hasn't handled it.

    base.OnTextInput(e);

    this.Output.Text = string.Format("Hit Count: {0}", ++mHitCount);

   // ... Handle pressed key ...
}

Ответы [ 2 ]

0 голосов
/ 04 ноября 2011

Я решил обойти эту проблему, используя следующую настройку:

private Key mPressedKey;

protected override void OnKeyDown(KeyEventArgs e)
{
    base.OnKeyDown(e);

    mPressedKey = e.Key;
}

protected override void OnTextInput(TextCompositionEventArgs e)
{
    base.OnTextInput(e);

    // ... Handle mPressedKey here ...
}

protected override void OnMouseDown(MouseButtonEventArgs e)
{
    base.OnMouseDown(e);

    // Force focus back to main window
    FocusManager.SetFocusedElement(this, this);
}

Это было сделано в MainWindow.xaml.cs.Это что-то вроде взлома, но он достиг желаемого результата.

0 голосов
/ 03 ноября 2011

Вы можете установить защиту на основе типа для этого оператора:

protected override void OnKeyDown(KeyEventArgs e)
{
    base.OnKeyDown(e);

    if (e.OriginalSource is TextBoxBase == false)
    {
        mPressedKey = e.Key;
    }
}

Вполне возможно, что и не самое лучшее решение.

...