Delphi - OnKeyPress происходит до того, как TStringGrid обновляет ячейку новым символом

Программирование в Delphi, присоединение обработчика события OnKeyPress к TStringGrid:

Событие OnKeyPress срабатывает до того, как ячейка сетки, которую вводит пользователь, фактически обновит свое значение с помощью нажатой клавиши. Это, очевидно, проблема, когда я хочу знать, каково содержимое этой ячейки в данный момент, например, когда пользователь изменяет его.

«Хакерское» решение простое, если вы не рассматриваете каждую деталь: просто возьмите значение из ячейки и, поскольку событие OnKeyPress поставляется вместе с параметром Key, добавьте это значение в конец - теперь у вас есть текущее значение ячейки!

Ложь. Что, если пользователь выделил весь текст в ячейке (например, «foo») и теперь набирает «b». Поскольку они выбрали текст, он будет стерт и заменен буквой «б». Однако значение ячейки по-прежнему будет отображаться как «foo» в OnKeyPress, а значение Key будет «b», поэтому приведенная выше логика приведет приложение к выводу, что ячейка теперь содержит "foob", что, как мы знаем, не соответствует действительности.

Итак. Кто-нибудь знает, как обойти эту проблему? Есть ли способ заставить OnKeyPress реагировать после обновления содержимого сетки или, возможно, способ принудительного обновления в начале обработчика? Я отчаянно избегаю использования события OnKeyUp здесь, поэтому любые предложения, кроме этого, будут очень признательны.


person JMTyler    schedule 07.04.2010    source источник
comment
Почему вы отчаянно избегаете использования события OnKeyUp?   -  person Mason Wheeler    schedule 07.04.2010
comment
OnKeyPress запускается до того, как элемент управления обработает ключ и соответствующим образом обновит свое содержимое. Это делается для того, чтобы код приложения мог заранее отклонить ключ, если это необходимо.   -  person Remy Lebeau    schedule 07.04.2010
comment
@Remy: Да, Deltics уже объяснила мне это, а также предоставила ответ вместе с ним. @Mason: OnKeyUp отслеживает все ключи, а не только ASCII, и отфильтровывать то, что мне не нужно, требует много ненужных усилий. У меня были проблемы с использованием OnKeyUp (например, перехват KeyUp, когда KeyDown был на другом компоненте — это нежелательно), поэтому я провел рефакторинг для использования OnKeyPress, так что было бы довольно бессмысленно возвращаться и использовать его снова. OnSetEditText у меня должен отлично работать.   -  person JMTyler    schedule 07.04.2010


Ответы (1)


Если вы хотите реагировать на изменение значения ячейки, почему вы не используете событие OnSetEditText?

События клавиатуры предназначены для ответа на ввод с клавиатуры, а не для реакции элементов управления на этот ввод. Элемент управления обычно предоставляет одно или несколько дополнительных событий, позволяющих приложению реагировать на реакцию элементов управления на некоторый ввод — в этом случае, когда ввод с клавиатуры приводит к изменению значения ячейки, а не к изменению выбора ячейки, например .

Кроме того, вполне естественно, что эти события должны происходить до реакции элементов управления сеткой на эти события, так что вы можете эффективно "фильтровать" такие события до их возникновения. добраться до элемента управления, например чтобы предотвратить влияние определенного ввода с клавиатуры на значение ячейки.

person Deltics    schedule 07.04.2010
comment
Технически OnSetEditText срабатывает всякий раз, когда ячейка теряет фокус, независимо от того, изменилось ли значение на самом деле. Тем не менее, если я сравню значения, чтобы увидеть, действительно ли они изменились, это должно работать чудесно для меня. Большое спасибо. - person JMTyler; 07.04.2010