(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

Смесь бульдога с носорогом

Источник: delphi2010
Алксандр Божко

В одном из предыдущих постов я упоминал о переводе Delphi проекта на DevExpress. Поскольку одной из основных причин такого решения была необходимость создания т.н. Ribbon -интерфейса, то в проекте пришлось менять все контролы. Сами понимаете, на фоне Ribbon-меню обычные серые кнопки, списки, радио-баттоны и чек-боксы смотрятся не очень... Очень быстро выяснилось, что переделать главное меню - не самое сложное. Компонент TdxBarConverter успешно решает эту задачу (требуется лишь легкая "доработка напильником"). Но если проект содержит несколько сотен контролов, которые активно используются в коде, то о трудоемкости их замены в ручную лучше и не говорить. К счастью существует несколько бесплатных расширений IDE, позволяющих автоматизировать этот процесс. Я пользуюсь, как мне кажется, лучшим из бесплатных решений - набором GExperts. Одной из его возможностей является автоматическая замена одного контрола на другой. При этом можно заменить не просто единичный элемент, но и все элементы на форме или в проекте. Конечно, заменять с помощью данного инструмента, такие сложные компоненты, как DBGrid не стоит. Все же у того же DBGridEh и cxGrid абсолютно разная структура. Но с DBComboBox'ами и прочими "простыми" контролами GExperts справляется не плохо. Если бы не одно "НО"... Учитывая то, что котнтролы DevExpress просто перенасыщены функциональностью, из создатели решили упростить жизнь своим клиентам (а возможно и себе). Ряд свойств большинства контролов был сгруппирован в отдельные классы. Так скажем, обратиться к списку значений TcxComboBox можно следующим образом:

cxComboBox.Proiperties.Items ...

в то время, как для VCL-евского TComboBox обращение будет выглядеть так:

ComboBox1.Items ...

Естественно, что мастер замены контролов не может развязать такие несовпадения и их приходится править вручную... Даже имея перед собой два монитора, я быстро пришел к выводу, что поэлементное сравнение каждой формы - занятие весьма утомительное. Решение же данной проблемы оказалось довольно простым.

unit cxATRComboBox;

interface

uses
  SysUtils, Classes, Controls, cxControls, cxContainer, cxEdit, cxTextEdit,
  cxMaskEdit, cxDropDownEdit;

type

  TcxATRComboBox = class(TcxComboBox)
  private
    FOnChange: TNotifyEvent;
    FOnDropDown: TNotifyEvent;

    function GetItems: Tstrings;
    procedure SetItems(const Value: Tstrings);
    function GetOnChange: TNotifyEvent;
    procedure SetOnChange(const Value: TNotifyEvent);
    function GetDropDown: TNotifyEvent;
    procedure SetDropDown(const Value: TNotifyEvent);
    { Private declarations }
  protected
    { Protected declarations }
  public
    { Public declarations }
   constructor Create(AOwner: TComponent); override;
  published
    { Published declarations }
     property Items: Tstrings read GetItems write SetItems;
     property OnChange: TNotifyEvent read GetOnChange write SetOnChange;
     property OnDropDown: TNotifyEvent read GetDropDown write SetDropDown;

  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Dev Express My Own', [TcxATRComboBox]);
end;

{ TcxATRComboBox }

constructor TcxATRComboBox.Create(AOwner: TComponent);
begin
  inherited;

end;

function TcxATRComboBox.GetDropDown: TNotifyEvent;
begin
 Result:= FOnDropDown;
end;

function TcxATRComboBox.GetItems: Tstrings;
begin
  Result:= self.Properties.Items;
end;

function TcxATRComboBox.GetOnChange: TNotifyEvent;
begin
Result:= FOnChange;
end;

procedure TcxATRComboBox.SetDropDown(const Value: TNotifyEvent);
begin
 self.Properties.OnPopup:=Value;
 FOnDropDown:= Value;
end;

procedure TcxATRComboBox.SetItems(const Value: Tstrings);
begin

  if Assigned(self.Properties.Items) then
    self.Properties.Items.Assign(Value)
  else
    self.Properties.Items := Value;

end;

procedure TcxATRComboBox.SetOnChange(const Value: TNotifyEvent);
begin
 self.Properties.OnChange:=Value;
 FOnChange:= Value;
end;

end.

Как видно из кода, мы просто создаем наследника для каждого из "неприятных" контролов. В этих наследниках мы попросту вводим "недостающие" свойства и считывая и записывая их значения ссылаемся на аналогичные имеющиеся в классе-родителе. Так у нас появляется свойство Items, хотя фактически работая с ним, мы работаем со свойством Properties.Items. И мастер замены компонентов доволен таким соответствием взаимозаменяемых классов и компилятор не ругается... Классический пример того как "лучше день потерять, но за пять минут долететь" (c).

Ссылки по теме


 Распечатать »
 Правила публикации »
  Написать редактору 
 Рекомендовать » Дата публикации: 21.09.2009 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
Delphi Professional Named User
Enterprise Connectors (1 Year term)
SAP CRYSTAL Server 2013 WIN INTL 5 CAL License
Inventory 9
Microsoft Office для дома и учебы 2019 (лицензия ESD)
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Безопасность компьютерных сетей и защита информации
Новости ITShop.ru - ПО, книги, документация, курсы обучения
Программирование на Microsoft Access
CASE-технологии
СУБД Oracle "с нуля"
Новые материалы
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100