Как в событии TDatePicker.OnCloseUp определить, нажал ли пользователь кнопку «Отмена»?

У меня, пожалуй, простой вопрос:

У меня есть TStringGrid в Delphi 10.4 и TDatePicker там, с помощью которого я хочу выбрать дату в FixedCol. Когда я нажимаю на ячейку заголовка, открывается TDatePicker, а также отображается сегодняшняя дата. Я заранее выбрал сегодняшнюю дату в мероприятии TForm.OnCreate для TDatePicker. Кроме того, у меня есть событие OnCloseUp для TDatePicker, которое записывает выбранную дату в ячейку.

Однако это происходит как при подтверждении с помощью галочки, так и при отмене с помощью X.

Как я могу запросить, нажал ли пользователь «Отмена», чтобы я не вводил значение?

Мой код примерно такой:

procedure TForm1.DatePicker1CloseUp(Sender: TObject);
begin
  //if DatePicker.Cancel ?? then
  //   exit;
  StringGrid1.Cells[col, row] := FormatDateTime(dateformat, DatePicker1.Date);
end;

Я только обнаружил, что если я выберу дату и нажму «ОК», я получу выбранную дату. Выбор другой даты и нажатие кнопки «Отмена» возвращает предопределенную дату.

Вы можете использовать событие OnChange, чтобы отреагировать на выбор даты пользователем. Обратите внимание, что событие вызывается также при установке даты в коде.

Peter Wolf 03.02.2023 12:24

Да, но с onChange-Event я не понимаю, когда пользователь хочет принять предварительно выбранную сегодняшнюю дату, поскольку он просто нажимает кнопку «ОК» и не меняет/выбирает дату

Syndi 03.02.2023 13:49

Кажется, что TDatePicker может быть неправильным элементом управления (как он реализован). Otoh, может быть, вы можете переосмыслить процесс: когда форма первоначально отображается, инициализируйте средство выбора даты с сегодняшней датой и автоматически загружайте сегодняшние данные (поскольку это обычный вариант использования). Затем, если пользователь хочет увидеть другой день, он использует TDatePicker, который теперь будет иметь действительную ссылку для суждения об изменении - не изменении.

Tom Brunberg 03.02.2023 14:51

да, похоже, если нет способа получить от TDatePicker, какая кнопка нажата. Но спасибо всем.

Syndi 03.02.2023 15:57

В этом случае вы можете создать подкласс TDatePicker и переопределить его метод AcceptDropDown. Если вы не хотите вводить новый компонент, вы можете использовать класс интерпозера.

Peter Wolf 03.02.2023 17:29
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
5
105
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Внутри элемент управления (TDatePicker) использует свойство Date для хранения значения. Прежде чем изменить значение компонента, вы можете загрузить это значение и сохранить его. В конце вы можете увидеть, есть ли изменения в свойстве Date по отношению к начальному значению.

Если изменений нет, это может быть связано с:

  • Смена отменена.
  • Выбрана та же дата.

В обоих случаях нет необходимости обновлять файл TStringGrid.

Протестируйте что-то вроде этого:

...
private
  oldValue:tDate;
...

procedure TForm3.DatePicker1Click(Sender: TObject);
begin
  oldDate := DatePicker1.Date;
end;

procedure TForm3.DateTimePicker1CloseUp(Sender: TObject);
begin
  if DatePicker1.Date <> OldDate then
    StringGrid1.Cells[col, row] := FormatDateTime('dd/mm/yyyy', DatePicker1.Date);
end;

спасибо, это правильно. Но я начинаю с пустой StringGrid-Cell, которая должна быть заполнена датой. Обычно пользователь может выбрать сегодняшнюю дату. Поэтому я хотел предварительно выбрать эту дату. Но при этом я не могу отличить отмену от выбора сегодняшней даты. Нет ли возможности узнать, какая кнопка нажата без сохраненного значения даты?

Syndi 03.02.2023 13:23
DatePicker1 против DateTimePicker1? TDatePicker и TDateTimePicker — совершенно разные компоненты. Какой из них вы вообще смотрели?
Remy Lebeau 03.02.2023 18:33

@Syndi «Нет ли возможности узнать, какая кнопка нажата без сохраненного значения даты?» - Предложение Питера кажется единственным надежным способом провести это различие.

Remy Lebeau 03.02.2023 18:40
Ответ принят как подходящий

Попробовав, я нашел решение, по крайней мере, для ввода с помощью мыши:

GetCursorPos(MausPos);
MausPos := DatePicker1.ScreenToClient(MausPos);
if (MausPos.X > DatePicker1.Width / 2)  then
  ShowMessage('Cancel')
else
  ShowMessage('OK');

Я беру позицию курсора относительно TDatePicker. Если координата X находится в правой половине, нажимается кнопка отмены, и я могу выйти из функции, не записывая дату в StringGrid.

Обратите внимание, что GetCursorPos() получает текущую позицию мыши, а не позицию, в которой она находилась, когда было сгенерировано событие щелчка. Для этого вы можете использовать GetMessagePos().

Remy Lebeau 03.02.2023 18:38

Другие вопросы по теме