У меня, пожалуй, простой вопрос:
У меня есть 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-Event я не понимаю, когда пользователь хочет принять предварительно выбранную сегодняшнюю дату, поскольку он просто нажимает кнопку «ОК» и не меняет/выбирает дату
Кажется, что TDatePicker
может быть неправильным элементом управления (как он реализован). Otoh, может быть, вы можете переосмыслить процесс: когда форма первоначально отображается, инициализируйте средство выбора даты с сегодняшней датой и автоматически загружайте сегодняшние данные (поскольку это обычный вариант использования). Затем, если пользователь хочет увидеть другой день, он использует TDatePicker
, который теперь будет иметь действительную ссылку для суждения об изменении - не изменении.
да, похоже, если нет способа получить от TDatePicker, какая кнопка нажата. Но спасибо всем.
В этом случае вы можете создать подкласс TDatePicker
и переопределить его метод AcceptDropDown
. Если вы не хотите вводить новый компонент, вы можете использовать класс интерпозера.
Внутри элемент управления (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, которая должна быть заполнена датой. Обычно пользователь может выбрать сегодняшнюю дату. Поэтому я хотел предварительно выбрать эту дату. Но при этом я не могу отличить отмену от выбора сегодняшней даты. Нет ли возможности узнать, какая кнопка нажата без сохраненного значения даты?
DatePicker1
против DateTimePicker1
? TDatePicker и TDateTimePicker — совершенно разные компоненты. Какой из них вы вообще смотрели?
@Syndi «Нет ли возможности узнать, какая кнопка нажата без сохраненного значения даты?» - Предложение Питера кажется единственным надежным способом провести это различие.
Попробовав, я нашел решение, по крайней мере, для ввода с помощью мыши:
GetCursorPos(MausPos);
MausPos := DatePicker1.ScreenToClient(MausPos);
if (MausPos.X > DatePicker1.Width / 2) then
ShowMessage('Cancel')
else
ShowMessage('OK');
Я беру позицию курсора относительно TDatePicker. Если координата X находится в правой половине, нажимается кнопка отмены, и я могу выйти из функции, не записывая дату в StringGrid.
Обратите внимание, что GetCursorPos()
получает текущую позицию мыши, а не позицию, в которой она находилась, когда было сгенерировано событие щелчка. Для этого вы можете использовать GetMessagePos().
Вы можете использовать событие OnChange, чтобы отреагировать на выбор даты пользователем. Обратите внимание, что событие вызывается также при установке даты в коде.