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

TIPS & TRICKS

В одном из постов, если не ошибаюсь в блоге у Всеволода Леонова, довелось мне прочесть про забавный кейс. В программе было предусмотренно ограничение длины поля ввода пароля. При том, ограничивалось оно тихо, просто “съедая” лишние символы. Естественно, что после этого с паролями возникла неразбериха. В принципе, вопрос ограничения длины поля ввода сам по себе является философским, а возможно даже теологическим, но просто взять и “откусить хвост” вводимому тексту, на мой взгляд – не совсем правильно. Однако, в большинстве случаев, если задать свойство 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;

Читать далее

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

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

Итак, дано:

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

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

Скины для dxRibbon

Как гласит официальная документация, для того, что бы применить скин для dxRibbon нужно изменить свойство ColoreSchemeName. Действительно, устанавливаем значения свойства как Office2010Silver и прямо в режиме проектирования видим как наш Ribbon bar преображается.

skinnedribbon

Однако запустив приложение видим следующее:

skinnedribbonold

Обычный голубой скин, который и был изначально. Какой бы скин мы не выбрали, ситуация не меняется. dxRibbon отображает только стандартные цветовые схемы – blue, black и silver.

В чем же проблема?

Читать далее

Если вы не любите читать сообщения, которые время от времени выдает вам IDE, то, возможно, данный пост сэкономит вам некоторое количество времени. Речь пойдет о скинах DevExpress. В меню Delphi выберите пункт Project | Modify Skin Options. на экране появится следующий диалог.

skinoptions

По умолчанию, включена поддержка всех скинов. Теперь, предположим, что вы, по каким-то причинам, не хотите использовать все скины. Все же бинарник разрастается, при их использовании. Здесь вы их можете отключить. Но, прежде чем это сделать внимательно прочтите Note.

В секции Uses модуля каждой формы объявления модулей с уже ненужными скинами останутся, и их нужно вычистить руками. Выглядят описания модулей так:

dxSkinOffice2010Blue, dxSkinOffice2010Green….

Что же произойдет, если этого не сделать? Во-первых, размер бинарника не уменьшится. Далее… Вполне вероятно, что в IDE ваш проект будет вести себя вполне пристойно. Чудеса начнутся как только вы попытаетесь запустить приложение вне среды разработки. Так у меня проект, упакованный с помощью ASPack, вообще не стартовал. Я долго не мог разобраться в чем причина, и только запустив редактор ресурсов и обнаружив в нем все скины из набора DevExpress Skin Library, догадался в чем дело.

Так что, будьте внимательны с объявлениями скинов.

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

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

В предыдущих постах я начал рассказывать о некоторых проблемах перевода приложения на Delphi с поддержкой юникод (2009/2010/XE). Одним из проявившихся артефактов стало некорректный формат ввода даты в DevExpress компонентах, при языка.

Скажем, когда мы устанавливаем чешский, то при попытке ввести дату по средствам компонента TcxDateEdit получаем следующее:

incorrect_date

Соответственно, при попытке осуществить ввод данных в таком формате, получаем ошибку (Could not convert variant of type (Unicode string) to type (Date)).

При этом в Delphi 2007 все работало без проблем. Тем не менее, как следует из материалов на официальном сайте DevExpress, пользователи продукта сталкивались с подобными проблемами и при работе с младшими версиями Delphi. Например, при попытке изменить формат даты в процессе выполнения приложение. Решение довольно простое.

Подключаем модуль cxFormats и выполняем следующий код:

cxFormatController.BeginUpdate;
cxFormatController.UseDelphiDateTimeFormats := True;
cxFormatController.EndUpdate;
cxFormatController.GetFormats;
cxFormatController.NotifyListeners;

Все становится на свои места.

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

DevExpress. TIPS & TRICKS #0
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
DevExpress. TIPS & TRICKS #7

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



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