(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
Enterprise Connectors (1 Year term)
Delphi Professional Named User
ABViewer Professional пользовательская
Quest Software. Toad for SQL Server Development Suite
FastReport.Desktop
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Новости ITShop.ru - ПО, книги, документация, курсы обучения
Программирование на Microsoft Access
CASE-технологии
СУБД Oracle "с нуля"
Компьютерные книги. Рецензии и отзывы
Утиль - лучший бесплатный софт для Windows
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100