Блог Александра Божко
Архивы
Рубрики

DevExpress

В одном из постов, если не ошибаюсь в блоге у Всеволода Леонова, довелось мне прочесть про забавный кейс. В программе было предусмотренно ограничение длины поля ввода пароля. При том, ограничивалось оно тихо, просто “съедая” лишние символы. Естественно, что после этого с паролями возникла неразбериха. В принципе, вопрос ограничения длины поля ввода сам по себе является философским, а возможно даже теологическим, но просто взять и “откусить хвост” вводимому тексту, на мой взгляд – не совсем правильно. Однако, в большинстве случаев, если задать свойство MaxLength для контрола, отвечающего за ввод текста, именно так и произойдет.

Компонент TcxTextEdit и другие компоненты из набора DevExpress  могут красиво решать данную проблему благодаря событию OnValidate.

Код, который я использую выглядит примерно так:

procedure TfrmEditBenefit.txtBenefitNamePropertiesValidate(Sender: TObject;
  var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean);
begin
 if Length(txtBenefitName.Text)>125 then
 begin
   ErrorText:= 'Benefit name value is too long.';
   Error:= True;
 end;
end;

Для наглядности можно показать значок ошибки рядом с полем ввода.

 

txtBenefitName.Properties.ValidationOptions:= [evoRaiseException, evoShowErrorIcon];

Выглядеть это будет примерно так:

TextValueIsTooLong

Ошибка генерируется если текст длиннее допустимого значения при попытке передать фокус другому контролу. При этом пользователь зразу видит что и где не так. По-моему очень удобно и наглядно.

Другие статьи серии:

DevExpress. TIPS & TRICKS #0
DevExpress. TIPS & TRICKS #1
DevExpress. TIPS & TRICKS #2
DevExpress. TIPS & TRICKS #3
DevExpress. TIPS & TRICKS #4
DevExpress. TIPS & TRICKS #5
DevExpress. TIPS & TRICKS #5.5
DevExpress. TIPS & TRICKS #6

Пришел от нашего клиента запрос примерно  следующего содержания. Раньше, в старые добрые времена, я мог вводить время в поле ввода не используя разделитель. Например, набираю 0800, а программа сама преобразует введенное значение в корректный формат – 08:00.

То, как это работало раньше (в EhGrid), я, естественно, не помню. Задача заключается в том, как заставить работать это cxGrid. Думаю, мне это удалось. Поэтому, очередной пост шпаргалка.

    procedure TFMain.cxDBGridDBTableView1TimeToPropertiesChange
      (Sender: TObject);
    begin
      if Length((Sender as TcxButtonEdit).EditText) = 2 then
        PostMessage((Sender as TcxButtonEdit).Handle, WM_CHAR, Ord(':'), 0);
    end;

Т. е. при вводе текста в поле я проверяю его длину и если она равна двум символам, отсылаем окну ввода разделитель времени. Разделитель у меня прошит жестко – ‘:’. Здесь важно, что тип поля у меня – TcxButtonEdit, а не, скажем, TcxTimeEdit. Почему так – отдельная история. Возможно, при использовании TcxTimeEdit задача бы решалась проще. Но имеем то, что имеем. В принципе, логичным было бы для Sender‘а изменить свойство EditText. Примерно так:

(Sender as TcxButtonEdit).EditText:= (Sender as TcxButtonEdit).EditText+':';

Но почему-то, курсор после выполнения такой операции возвращается в начало строки. Поэтому пришлось делать так.

Вполне допускаю, что данное решение совершенно не оптимальное. Но, работает.

 

Другие статьи серии:

DevExpress. TIPS & TRICKS #0
DevExpress. TIPS & TRICKS #1
DevExpress. TIPS & TRICKS #2
DevExpress. TIPS & TRICKS #3
DevExpress. TIPS & TRICKS #4
DevExpress. TIPS & TRICKS #5
DevExpress. TIPS & TRICKS #5.5
DevExpress. TIPS & TRICKS #7

Предыдущий пост вызвал довольно оживлённую дискуссию относительно оптимальности приведенного решения. Напомню, что ставилась задача в отфильтрованном гриде необходимо некоторым образом модифицировать все записи. Действительно, приведенный вариант был далеко не оптимальный. С подачи резидента DevExpress (Константин, спасибо) я набросал еще несколько вариантов решения данной задачи.

Наиболее приемлемым мне показался этот:

if cxDBGridDBTableView1Approved.Filtered then
  cxDBGridDBTableView1Approved.Filtered:= False;

qryTiming.filter:= cxDBGridDBTableView1.DataController.Filter.FilterText;
 qryTiming.DisableControls;
 qryTiming.filtered:= True;
 qryTiming.first;

 while not  qryTiming.Eof do
 begin
   qryTiming.Edit;
   qryTimingApproved.AsInteger:= Approving;
   qryTiming.Post;
   qryTiming.Next;
 end;

qryTiming.filtered:= False;
qryTiming.EnableControls;

Обратите внимание на то, если изменяемое поле присутствует в условии фильтрации, то фильтр по нему сбрасывается. В противном случае, проход через все записи в наборе данных не будет обработан корректно. Так устроен  DataSet. Читать далее

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

for I := 0 to cxDBGridDBTableView1.DataController.FilteredRecordCount - 1 do
  begin
    cxDBGridDBTableView1.DataController.FocusedRecordIndex:=
      cxDBGridDBTableView1.DataController.FilteredRecordIndex[I];

      cxDBGridDBTableView1.DataController.DataSet.Edit;
      qryTimingApproved.AsInteger:= 1;

      cxDBGridDBTableView1.DataController.DataSet.Post;
  end;

Читать далее

Как я уже упоминал, на работе для разработки приложений была приобретена полная VCL Subscription от DevExpress. До этого у нас имелись лишь отдельные пакеты, к тому же они приобретались более года назад и многие продукты успели обновиться. К сожалению, мне не сразу удалось установить обновления и посмотреть последнюю версию DevExpress. Между тем, изменения обратили на себя внимание практически сразу. Помните, я писал о том, как создать “правильную” ribbon форму c помощью DevExpress (сколько раз обещал себе провести на блоге субботник и систематизировать все записи)? Так вот, теперь все стало довольно просто и среди списка стандартных Delphi файлов которые можно создать (File|New|Other… Delphi Files) появилось два вида DevExpress форм – хорошо знакомая ribbon форма в стиле офиса 2007 и новая – в стиле офиса 2010.

devexpress_new_delphi_project

Сия новинка пришлась весьма кстати, поскольку я уже собирался изощряться и создавать нечто подобное руками. К счастью, делать этого не пришлось. В данном посте я и попытаюсь рассказать о том, что из себя представляет DevExpress VCL v 12.1 Ribbon 2010 Form и как с ней работать. Читать далее

Сегодня я снова вернусь к “жизнеописанию” своего проекта. Возможно, в этом посте вы найдете еще один аргумент, для того, что бы перейти на Delphi XE2. Начну я с небольшого вступления.

На семинаре Embarcadero в Киеве в сентябре прошлого года я услышал историю о переводе на юникод очень большого проекта. Собственно, и истории ни какой не было. Был проект, который разработчики, с одной стороны, и хотели бы перевести на старшую версию Delphi. А с другой стороны у них в проекте 5 млн. строчек кода. И, естественно, перспектива рефакторинга и последующего тестирования такого количества кода их весьма пугает. А так ли страшно это на самом деле?

Я уже говорил, что проект у меня относительно не большой. Но вчера я обнаружил, что у меня у самого 0,6 млн. строк. Т.е. в теории выйти на сопоставимые порядки сложности приложения вполне реально, даже если не решать “сверхзадач” (я ни в коем случае не призываю оценивать сложность проекта количеством кода!).

Но таким объемом кода надо эффективно управлять и контролировать его. Конечно, hint’ы и warning’и помогают хоть как-то избегать ляпов. Но довольно часто разработчики просто не обращают на них внимания (что в корне не правильно), тупо полагаясь на оптимизатор.  Даже в довольно именитых наборах компонентов, при сборке исходников hint’ы и warning’и встречаются в изобилии. И полная ревизия всех сообщений компилятора – задача не простая.

И вот здесь очень удобно использовать QA Audits – инструмент, впервые появившийся в Delphi 2010. Использовать это средство в полном объеме могут владельцы Enterprise, Ultimate и Architect редакций Delphi. Читать далее

Размышления на тему обращения к полям DataSet

Читать чужой код – занятие, порой, весьма увлекательное. Иногда узнается нечто новое, а иногда появляется иное видение, казалось бы хорошо знакомых вещей.

В этом посте речь,  пойдет о том как в коде приложения удобнее всего обращаться к полям DataSet. Вариантов, казалось бы не так уж и много, да и все они давно и хорошо изучены. Но,  все-равно есть о чем задуматься…

В некоторой степени этот вопрос уже был затронут в болге Delphi Notes.

В начале немного теории. По умолчанию, при размещении экземпляра TDataSet на форме, Delphi автоматически создает наследников TFields для каждого поля в наборе данных, с учетом типов этих полей. В режиме проектирования (design mode) можно заменить эти поля на постоянные с помощью редактора полей. Лично я всегда предпочитаю всегда создавать поля в редакторе. Кроме того, мы можем добавить вычисляемые (calculated) и выпадающие (lookup) поля. Читать далее

“Раскрашиваем” cxGrid.

Тема заливки строк разными цветами, в зависимости от значения полей – весьма актуальна для любых гридов. Почему-то мне казалось, что я уже писал о том как это сделать в cxGrid, однако перелистав предыдущие статьи рубрики, я не нашел ничего подобного. Исправляюсь.

Итак, дано:

Поле ‘sales’ таблицы, к которой привязан cxGrid1DBTableView1 принимает значения 0 или 1. Необходимо строки, в которых значение sales равно 0 сделать серыми.

В данном случае определяем обработчик события OnCustomDrawCell. Код будет выглядеть примерно так: Читать далее

Боремся со скоростью!

В предыдущем посте я затронул проблему производительности приложения, использующего DevExpress компоненты. Здесь я расскажу о некоторых своих изысканиях в данном направлении.

Итак, имеем следующее…

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

К набору данных привязаны cxGrid, в котором активное представление TcxDBGridDBTableView и cxPivotGrid (еще один очень интересный компонент из набора DevExpress о котором обязательно стоит рассказать). При загрузке свыше тысячи записей наблюдается явственная протормозка.

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

Я попытался вычислить количество миллисекунд, затрачиваемых на открытие DataSet’а и на загрузку данных в Grid’ы примерно так: Читать далее

Данный пост я оформлю тезисно. Да и вопросов в нем больше чем ответов.

Не буду оригинален – текучка.

После перевода приложения на Delphi 2010 вдруг перестали работать отчеты. при том все сразу. Причина банальна – Rave Reports. Раздел QC, посвященный Rave уже можно читать как увлекательный роман. Там даже есть крики отчаяния, зачем, мол, использовать в такой хорошей IDE как Delphi неработающий Rave, если есть работающий FastReport. Убедил руководство перевести 14 отчетов на FR с попутной его покупкой. Благо дело, стоит не дорого. В последний момент струхнул. Полез ковырять Rave. Выяснилось, что встроенный Pascal Script не корректно отрабатывает if. Если чего-то целочисленное сравнивать с нулем, и результат оказывается false – отчет валится.

Вынес в код приложения все, что считалось в отчете. 2 недели работы.

Вторая задача, ставшая на повестке дня – производительность.

Притормаживает программа с DevExpress гридами. У меня есть подозрения на этот счет. Но пока не готов это обсуждать. По факту решения проблемы ждите продолжения рубрик “Заметки на полях” и “Tips & Trics”.

По данной теме, пожалуй все… Был краток, как и обещал.

И немного новостей:

Очередной номер BPM. Опять 60 страниц. Во многом благодаря стараниям наших авторов. Так что, подписывайтесь на русскую версию журнала и читайте статьи в оригинале :).

Другие статьи серии:

Редизайн интерфейса приложения. #0
Редизайн интерфейса приложения. #1
Редизайн интерфейса приложения. #2
Редизайн интерфейса приложения. #3
Редизайн интерфейса приложения. #4
Редизайн интерфейса приложения. #6
Редизайн интерфейса приложения. #7
Редизайн интерфейса приложения. #8

Продукты DevArt
Купить онлайн:



Читай русскоязычные Delphi блоги
Каталог блогов Blogdir.ru
Яндекс.Метрика