Вчера я рассмотрел большинство свойств компонента TjvTFDays, которые касались настройки внешнего вида компонента и для рассмотрения которых не требовалось писать какой-либо код, чтобы увидеть как эти свойства работают.
Сегодня рассмотрим оставшиеся свойства, которые касаются настройки внешнего вида событий в сетке расписания, научимся создавать сетку по шаблону и частично затронем рассмотрение методов компонента.
Для начала, создадим новый проект в Delphi и разместим на главной форме приложения два компонента: TjvTFDays – сетку расписания и TjvTFScheduleManager – менеджер расписаний. В свойстве ScheduleManager у TjvTFDays укажем наш менеджер
Теперь создадим колонку расписания. Для этого выбираем на форме компонент jvTFDays1 переходим в Object Inspector и открываем редактор свойства Cols.
Добавляем в коллекцию один элемент и выставляем у него следующие свойства:
SchedDate – 21.01.2011 (прим. – для реализации примера указываем текущий день)
SchedName – “Первое расписание”
Оставшиеся свойства оставляем по умолчанию.
Теперь напишем такой обработчик события у JvTFDays1:
procedure TForm1.JvTFDays1DblClick(Sender: TObject); var I: Integer; Appt: TJvTFAppt; begin Appt := JvTFDays1.ScheduleManager.dbNewAppt(''); With Appt do Begin Appt.BeginUpdate; Try SetStartEnd(Now, Now, Now, IncHour(Now)); Description := 'Описание события'; Appt.AddSchedule(JvTFDays1.Cols[0].SchedName); Finally Appt.EndUpdate; End; End end;
Разберемся вначале, что мы сделали в обработчике, а затем перейдем к рассмотрению свойств компонента. Итак:
Вначале мы создаем новый объект TJvTFAppt и размещаем его в менеджере расписаний. Этот объект будет хранить информацию об отдельном событии.
Далее, мы устанавливаем время начала и окончания события, воспользовавшись методом SetStartEnd объекта TJvTFAppt:
SetStartEnd(Now, Now, Now, IncHour(Now));
Метод SetStartEnd принимает следующее описание:
SetStartEnd(NewStartDate: TDate; NewStartTime: TTime; NewEndDate: TDate; NewEndTime: TTime)
NewStartDate – дата начала события
NewStartTime – время начала события
NewEndDate – дата окончания события
NewEndTime – время окончания события.
При установке даты и времени события мы также воспользовались функцией IncHour, которая нарастила текущее время на 1 час. Для тех, кто не в курсе – эта функция входит в состав замечательного модуля DateUtils, который достаточно подключить в uses главного модуля.
Далее, мы заполнили ещё одно свойство объекта Appt – описание (Description) и, наконец, разместили новое событие в сетке, а точнее в недавно созданном столбце с названием “Первое расписание”:
Appt.AddSchedule(JvTFDays1.Cols[0].SchedName);
Теперь посмотрим, что у нас в итоге получилось. Запустите приложение, сделайте двойной клик по сетке и промотайте сетку до текущего времени. У меня получилось следующее:
Создано событие продолжительностью в 1 час. Каждое событие в расписании выглядит как прямоугольник со следующими элементами:
Полоса события используется для того, чтобы визуально показать время действия события
Линии захвата появляются, когда событие выделено пользователем и используются следующим образом:
нижняя линия – для изменения времени действия события (“растягивания”)
верхняя линия – для перетаскивания события по сетке, в том числе и между различными столбцами сетки.
Изменим внешний вид нашего события. Вначале поменяем цвет области описания. Для этого используется группа свойств компонента JvTFDays1 под названием ApptAttr.
Свойства ApptAttr (SelApptAttr) позволяют настроить следующие атрибуты области описания события в обычном и выделенном состояниях:
Color:TColor – цвет области описания
Font: TFont – шрифт
FrameWidth: integer – толщина рамки области описания.
Изменив эти свойства можно получить, например, вот такой внешний вид события:
Теперь, рассмотрим свойства полосы события.
Свойства ApptBar используются для настройки полосы события. Можно настроить следующие свойства:
Color:TColor – цвет полосы
TimeStampColor: TColor – цвет линии времени
TimeStampStyle – стиль линии времени
Visible: boolean – видимость полосы события
Width: integer – толщина линии.
В целом все понятно без лишних рисунков, за исключением, может быть, линии времени. Для демонстрации того, что она из себя представляет я изменил свойства ApptBar следующим образом:
Color = clWhite
TimeStampColor = clRed
TimeStampStyle = tssBlock
Width = 20
Полоса события примет следующий вид:
Полоса времени точно указывает на время действия события. В приведенном выше случае полоска времени отображена как простой прямоугольник со сплошной заливкой. Дополнительно можно настроить её внешний вид, изменив свойство TimeStampStyle и получить, например такой вид (tssFullI):
или такой вид (tssHalfI):
Соответственно значение tssNone полностью убирает полосу времени.
С внешним видом событий в сетке расписания разобрались. Теперь более пристально посмотрим на работу с самой сеткой.
В приведенном выше примере программы мы воспользовались свойством Cols для создания столбца сетки. Кроме такого способа создания сетки в TjvTFDays есть ещё один, который удобно использовать в случае больших сеток, скажем на неделю, 10 дне и т.д. Этот способ основывается на использовании группы свойств, которые называются Template (шаблон).
Для первого примера работы с шаблонами сделаем точно такую же сетку какая есть уже в приложении. Для этого удалите из коллекции Cols столбец, перейдите на вкладку свойств Template и задайте такие свойства шаблона:
ActiveTemplate = agtLinear
LinearEndDate = 21.01.2011
LinearStartDate = 21.01.2011
LinearName = “Первое расписание”
В итоге Вы получите точную копию сетки из примера, но уже без непосредственного использования коллекции Cols. Элементы коллекции будут добавляться автоматически, исходя из того, какие вы свойства зададите шаблону. Например, у нас есть три человека- Вася, Петя, Коля. Нам необходимо отобразить в одной сетке их распиания. Как это сделать с помощью шаблона? Достаточно просто:
1. Добавляем в свойство CompNames: TStringList три строки: “Вася”, “Петя”, “Коля”
2. Выставляем значение свойства ActiveTemplate равным agtComparative
В итоге получаем такую сетку:
Использование шаблонов позволяет достаточно просто в рантайме регулировать внешний вид сетки расписания, не прибегая к работе с коллекцией Cols.
Теперь доработаем наш пример, чтобы продемонстрировать ещё пару методов TJvTFDays. Изменим наш обработчик события следующим образом:
procedure TForm4.JvTFDays1DblClick(Sender: TObject); var I: Integer; Appt: TJvTFAppt; ApptStartDate, ApptEndDate: TDate; ApptStartTime, ApptEndTime: TTime; begin If JvTFDays1.ValidSelection Then Begin ApptStartDate := JvTFDays1.Cols[JvTFDays1.SelStart.X].SchedDate; ApptEndDate := JvTFDays1.Cols[JvTFDays1.SelEnd.X].SchedDate; ApptStartTime := JvTFDays1.RowToTime(JvTFDays1.SelStart.Y); ApptEndTime := JvTFDays1.RowEndTime(JvTFDays1.SelEnd.Y); Appt := JvTFDays1.ScheduleManager.dbNewAppt(''); With Appt do Begin Appt.BeginUpdate; Try SetStartEnd(ApptStartDate, ApptStartTime, ApptEndDate, ApptEndTime); Description := 'Описание события'; Appt.AddSchedule(JvTFDays1.Cols[0].SchedName); Finally Appt.EndUpdate; End; End End; end;
В принципе листинг не нуждается в пространных комментариях, но, для порядку рассмотрим основные моменты.
Метод ValidSelection проверяет является ли выделенная ячейка таблицы ячейкой для записи события (мы ведь можем и по заголовку кликнуть).
Если кликнули по ячейке, для которой можно определить время, то приступаем к определению значений переменных. Свойство SchedDate каждой колонки (элемент коллекции Cols) содержит значение даты – это значение мы присваиваем переменным ApptStartDate и ApptEndDate.
Затем считываем значения времени. Для этого мы воспользовались методом RowToTime:
RowToTime(RowNum: Integer): TTime
В качестве входящего параметра задается номер строки в которой находится выделенная ячейка, а результатом будет значение времени. Как не трудно догадаться, результат выполнения функции RowToTime зависит от значения свойства Granularity, о котором я упоминал в прошлой статье. В нашем примере событие имеет продолжительность 30 минут (дефолтное значение Granularity).
Остался последний момент – вставка изображений в события. Для этого разместим на форме ImageList, загрузим в него пару картинок 16х16 пикселей и укажем его в свойстве StateImages компонента JvTFScheduleManager1. Здесь же (в свойствах JvTFScheduleManager1) открываем вкладку свойств StateImageMap и указываем Modified = 1, а в обработчике события дописываем всего одну строку:
Appt.SetModified;
Теперь все события, добавляемые в расписание будут иметь картинку с индексом 1 в ImageList’e. Если необходимо задать уникальное изображение для события, то можно воспользоваться свойством Glyph объекта TJvTFAppt, но это уже совсем другая история о которой поговорим позднее.
Спасибо за данные статьи по органайзеру. Жду продолжения. и как можно побыстрее и по чаще.
Спасибо, много всего интересного на сайте, но как-то неудобно пользоваться, как будто всё просто свалено, нет возможности както структурировать статьи?
Все статьи по категориям. Это же блог, а не каталог статей :) Статьи идут в обратном хронологическом порядке. Там где можно было объединить несколько статей в подборку, сейчас периодически вставляю ссылочки на следующую и предыдущую статью из цикла
В первой же процедуре: procedure TForm1.JvTFDays1DblClick(Sender: TObject);
Запускаю, кликаю по ячейке и получаю ошибку.
Access Violation … Read of address 00000000.
На Delphi7 и на ХЕ2 одна и та-же ошибка.
Что не нравиться?
п.с. библ JVCL347