2015-04-02 2 views
4

Я использую TDateTimePicker, чтобы пользователь мог выбрать день (либо вручную, либо путем нажатия кнопок для перехода вперед или назад на один день). Затем пользователь увидит записи журнала за этот конкретный день.Показать недопустимые даты с отключенным в TDateTimePicker

Управление отлично работает, но я хочу ограничить пользователя между [OLDEST-DAY-IN-LOG] и [СЕГОДНЯ], поскольку это ограничения по дате, когда есть данные.

Я установил MinDate и MaxDate на TDateTimePicker, и это работает нормально. Выбор даты вне разрешенного диапазона ничего не делает.

Мой вопрос заключается в том, можно ли нарисовать недопустимые даты, выделенные серым цветом. В прикрепленном изображении выбранная дата - 01/04, а сегодня - 02/04. Я хотел бы видеть 03/04 (и позже) отключенным. В идеале, как «30» и «31», вы видите изображение, которое является последним днем ​​марта.

Возможно ли это? Использование Delphi 7, если это необходимо.

TDateTimePicker control in Delphi

+1

MinDate и MaxDate установлены (указано в вопросе), и что работает. Когда пользователь выбирает 03/04, элемент управления не генерирует событие OnChange или CloseUp. Пометив недействительные даты, пользователь, по крайней мере, поймет, почему ничего не произошло. – AlainD

+0

Используйте TMonthCalendar, и если вы используете xpmanifest, диапазон между min-max - это только видимые дни. –

+0

@SertacAkyuz: Интересная идея использовать TMonthCalendar, никогда не использовала один из них раньше. Мой выбор даты небольшой и в верхней части формы, как выпадающий список. Кажется, что TMonthCalendar имеет (довольно большой) минимальный размер, что делает его непригодным для моего пользовательского интерфейса. Не удалось увидеть какие-либо свойства, чтобы изменить свой стиль, это можно сделать? – AlainD

ответ

2

TDateTimePicker является оболочкой для Win32 DTP control, который не обеспечивает функциональность, которую вы ищете. Нет возможности для индивидуального рисования раскрывающегося календаря, и доступны только доступные стили дня: нормальный и bold.

+0

Спасибо Реми. Ничто не сразу подскакивает мне в перечисленных свойствах и методах, чтобы установить формат * bold * и посмотреть, как он выглядит. Это может сработать, если я смогу установить минуты/максимальные даты жирным шрифтом ... – AlainD

+0

@AlainD: Посмотрите свойство 'BoldDays'. –

+1

@KenWhite: ['BoldDays'] (http://docwiki.embarcadero.com/Libraries/XE7/en/Vcl.ComCtrls.TCommonCalendar.BoldDays) - это метод, а не свойство. Он готовит массив состояний дня, но фактически не присваивает этот массив DTP. Вы должны использовать ['OnGetMonthInfo'] (http://docwiki.embarcadero.com/Libraries/XE7/en/Vcl.ComCtrls.TCommonCalendar.OnGetMonthInfo) или [' OnGetMonthBoldInfo'] (http: //docwiki.embarcadero. com/Libraries/XE7/en/Vcl.ComCtrls.TCommonCalendar.OnGetMonthBoldInfo) для этого или перехватить уведомление 'MCN_GETDAYSTATE'. См. Http://stackoverflow.com/questions/7210565/ –

1

Как уже упоминалось в комментариях и ответе только стили normal and bold можно использовать. С TYearBoldManager вы можете реализовать это.

только набор марта 30,31 и апреле 1,2,3,4

Испытано: Delphi5 на победу XP/3

minDate = 2015/03/30 и maxDate = 2015/04/04

вы можете установить bold даты с

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    MonthCalendar1.CalColors.MonthBackColor := $6A7678; 
    MonthCalendar1.CalColors.TextColor := $4D5858; 

    FYearBoldManager := TYearBoldManager.Create; 
    FYearBoldManager.MakeBold(3, 30); 
    FYearBoldManager.MakeBold(3, 31); 
    FYearBoldManager.MakeBold(4, 1); 
    FYearBoldManager.MakeBold(4, 2); 
    FYearBoldManager.MakeBold(4, 3); 
    FYearBoldManager.MakeBold(4, 4); 
    ... 
end; 

Затем вы должны изменить значения цвета, чтобы получить наилучший контраст. Вот только предложение.

enter image description here

enter image description here

для тестирования Есть 4 файлов here , MonthCalendarDemo

Update:

MonthCalendarDemo.dpr

program MonthCalendarDemo; 

uses 
    Forms, 
    Unit1 in 'Unit1.pas' {Form1}, 
    UMonthBoldStorage in 'UMonthBoldStorage.pas'; 

{$R *.RES} 

begin 
    Application.Initialize; 
    Application.CreateForm(TForm1, Form1); 
    Application.Run; 
end. 

Посмотрите на UMonthBoldStorage.pas как это делается.


В чем разница?

enter image description here

Эксперты признали его.

к правой TDateTimePicker

Слева на TMonthCalendar и TComboBox

Преимущество:

  • Нет мин- MaxDate нужен
  • может иметь days without logfile.
  • полный контроль над календарем.
  • смелые дни просты в использовании
  • может видеть, где вы щелкнули (посмотрите на красивую пунктирную границу на 25, но не влияет на календарь).
  • не исчезает, если вы нажмете на неправильную дату. (Можете щелкнуть столько, сколько хотите, календарь исчезнет только при двойном щелчке по жирным дням. Здесь: дни 20 и 22).

enter image description here

  • можно щелкнуть внутри TComboBox или на down-arrow или при фокусировке хита ENTER открывает календарь и приносит вам последнюю дату с логфайлом.

enter image description here

enter image description here

  • оттуда вы можете удобно, с помощью клавиш со стрелками, месяцы с дней, которые имеют логфайл пройти.

enter image description here

все описанное может быть достигнуто с помощью нескольких строк дополнительного кода

procedure TForm1.MonthCalendar1DblClick(Sender: TObject); 
var 
    year, month, day : Word; 
begin 
    DecodeDate(MonthCalendar1.Date,Year, Month, Day); 
    if FYearBoldManager.GetDayStatus(month, day) then begin 
     if ValidDate then MonthCalendar1.Visible:=False; 
    end; 
end; 

procedure TForm1.MonthCalendar1Click(Sender: TObject); 
var 
    year, month, day : Word; 
begin 
    DecodeDate(MonthCalendar1.Date,Year, Month, Day); 
    if FYearBoldManager.GetDayStatus(month, day) then begin 
     lastValidDate := MonthCalendar1.Date; 
     ValidDate:=True; 
    end else begin 
     MonthCalendar1.Date := lastValidDate; 
     ValidDate:=False; 
    end; 
end; 

function TForm1.getComboBoxText(var validText:AnsiString):Boolean; 
var 
actText :AnsiString; 

begin 
    if ComboBox1.Text = '' then actText := validText else actText := ComboBox1.Text; 
    Try 
    MonthCalendar1.Date := StrToDateTime(Copy(actText,1,10)); 
    if actText <> validText then validText := actText; 
    lastValidDate := MonthCalendar1.Date; 
    ValidDate:=True; 
    Result := True; 
    except 
     Result := False; 
    end; 
end; 

procedure TForm1.ComboBox1Click(Sender: TObject); 
begin 
    if getComboBoxText(validText) then MonthCalendar1.Visible:=True; 
end; 

procedure TForm1.ComboBox1KeyUp(Sender: TObject; var Key: Word; 
    Shift: TShiftState); 
begin 
    if getComboBoxText(validText) then MonthCalendar1.Visible:=True; 
end; 
+0

Обратите внимание, что этот код применяется к 'TMonthCalendar', а не' TDateTimePicker', который использует @AlainD. –

Смежные вопросы