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

DevExpress.cx VirtualVerticalGrid как средство редактирование и отображения данных таблицы БД

Источник: deeptown12
Кузан Дмитрий

Добрый день!

В этом посте пойдет речь, о небольшой полезняшке позволяющий превратить стандартный DevExpress-овский компонент cxVirtualVerticalGrid в средство отображения и редактирования данных таблицы БД.
Предыстория:Мне очень импонирует представления данных таблиц БД в виде так сказать вертикального списка, разворачивающегося по подразделам. Что бы-было понятно о чем пойдет разговор представлю фрагмент скриншота из реально существующе программы, в нижней части он и представлен:

 
 
В общем захотелось мне такой список, да вот беда в стандартной DevExpress поставке такого компонента (который представлял DB-данные одной записи нет). Есть стандартный cxDbVerticalGrid но он не умеет предоставлять только 1 запись на просмотр, а предоставляет весь датасет, что согласитесь для моего случая не совсем то что нужно, т.к. он аналог грида только вертикальный. Мне же нужно было только видеть данные текущей записи (та которая в фокусе). Некий похожий компонент по функциональности компонент был в пакете InfoPower Professional, но ставить его я не хотел. 
И тут мой взгляд упал на  cxVirtualVerticalGrid который позволяет отображать собственные данные из класса наследника TcxCustomDataSource.
В общем пришлось написать посредника между cxVirtualVerticalGrid и datasource БД. Задача стояла так, что бы по колонке делался запрос к БД и выводилось значение в строку  cxVirtualVerticalGrid связанного с полем БД.  Ну и обратный процесс изменения данных в cxVirtualVerticalGrid-е попадал в БД. Этакий бонус - редактор полей БД, хоть и усеченный. 
Вообщем поколдовав денек тродилась такое решение, в виде класса TBrokerDataSource:

001  unit _Class.BrokerDB;  
002    
003  interface 
004    
005  uses 
006    Classes, cxCustomData, Variants, DB, DBCtrls;  
007    
008  type 
009      
010    TBrokerField = class(TCollectionItem)  
011    private 
012      FFieldName: String;  
013      procedure SetFieldName(const Value: String);  
014    public 
015    published 
016       Property FieldName : String  read FFieldName write SetFieldName;  
017    end;  
018      
019    TBrokerFieldList = class(TCollection)  
020    private 
021      function  GetItems(Index: Integer): TBrokerField;  
022      procedure SetItems(Index: Integer; const Value: TBrokerField);  
023    public 
024      Function  Add: TBrokerField;  
025      property  Items[Index: Integer]: TBrokerField read GetItems write SetItems; default;  
026    end;  
027    
028    TBrokerDataSource = class(TcxCustomDataSource)  
029    private 
030      FModified        : boolean;  
031      FBrokerFieldList : TBrokerFieldList;  
032      FDataSource  : TDataSource;  
033      procedure SetBrokerFieldList(const Value: TBrokerFieldList);  
034    
035      procedure SetDataSource(const Value: TDataSource);  
036      function  GetDataSource: TDataSource;  
037      Procedure DataChange(Sender: TObject; Field: TField);  
038    protected 
039      function  GetRecordCount: Integer; override;  
040      function  AppendRecord: TcxDataRecordHandle; override;  
041      procedure DeleteRecord(ARecordHandle: TcxDataRecordHandle); override;  
042      function  GetValue(ARecordHandle: TcxDataRecordHandle;  
043                         AItemHandle: TcxDataItemHandle): Variant; override;  
044      function  InsertRecord(ARecordHandle: TcxDataRecordHandle): TcxDataRecordHandle; override;  
045      procedure SetValue(ARecordHandle: TcxDataRecordHandle;  
046                AItemHandle: TcxDataItemHandle; const AValue: Variant); override;      
047    public 
048      constructor Create;  
049      destructor Destroy; override;  
050      property Modified: boolean read FModified;  
051    published 
052      Property DataSource: TDataSource Read GetDataSource Write SetDataSource;  
053      property Fields    : TBrokerFieldList read FBrokerFieldList write SetBrokerFieldList;  
054    end;  
055    
056    
057  implementation 
058    
059  { TCustomDataSource } 
060  constructor TBrokerDataSource.Create;  
061  begin 
062   FBrokerFieldList := TBrokerFieldList.Create(TBrokerField);  
063  end;  
064    
065  destructor TBrokerDataSource.Destroy;  
066  begin 
067   FBrokerFieldList.Free;  
068   inherited;  
069  end;  
070    
071  //------------------------------------------------------------------------------  
072  function TBrokerDataSource.GetRecordCount: Integer;  
073  begin 
074   Result := 1 
075  end;  
076    
077  function TBrokerDataSource.GetValue(ARecordHandle: TcxDataRecordHandle;  
078                                           AItemHandle: TcxDataItemHandle): Variant;  
079  var 
080    AColumnId : Integer;  
081    FN : String;  
082    I : Integer;  
083  begin 
084    Result := '<Нет данных>';  
085    if Assigned(DataSource) then 
086    begin 
087       if Assigned(DataSource.DataSet) then 
088       begin 
089         I := Integer(AItemHandle);  
090         if I < FBrokerFieldList.Count then 
091         begin 
092           FN := FBrokerFieldList[I].FieldName;  
093           Result := DataSource.DataSet.FieldByName(FN).AsVariant;  
094         end;  
095       end;  
096    end;  
097  end;  
098    
099  procedure TBrokerDataSource.SetValue(ARecordHandle: TcxDataRecordHandle;  
100                                            AItemHandle: TcxDataItemHandle;  
101                                            const AValue: Variant);  
102  var 
103    FN : String;  
104    I : Integer;  
105  begin 
106   I := Integer(AItemHandle);  
107   if I < FBrokerFieldList.Count then 
108   begin 
109      if Assigned(DataSource.DataSet) then 
110      begin 
111         FN := FBrokerFieldList[I].FieldName;  
112         if not DataSource.DataSet.Modified then 
113            DataSource.DataSet.Edit;  
114         DataSource.DataSet.FieldByName(FN).AsVariant := AValue;  
115         DataSource.DataSet.Post;  
116      end;  
117   end;  
118  end;  
119    
120    
121  function TBrokerDataSource.AppendRecord: TcxDataRecordHandle;  
122  //var  
123  //  AStatElement: TStatElement;  
124  begin 
125  //  AStatElement := TStatElement.Create;  
126  //  Result := TcxDataRecordHandle(FStatElementList.Add(AStatElement));  
127  //  DataChanged;  
128  //  if not Modified then  
129  //    FModified := True;  
130  end;  
131    
132  function TBrokerDataSource.InsertRecord(ARecordHandle: TcxDataRecordHandle): TcxDataRecordHandle;  
133  //var  
134  //  AStatElement: TStatElement;  
135  begin 
136  //  AStatElement := TStatElement.Create;  
137  //  FStatElementList.Insert(Integer(ARecordHandle), AStatElement);  
138  //  Result := TcxDataRecordHandle(ARecordHandle);  
139  //  DataChanged;  
140  //  if not Modified then  
141  //     FModified := True;  
142  end;  
143    
144  procedure TBrokerDataSource.DataChange(Sender: TObject; Field: TField);  
145  begin 
146   DataChanged;  
147  end;  
148    
149  procedure TBrokerDataSource.DeleteRecord(  
150    ARecordHandle: TcxDataRecordHandle);  
151  begin 
152    DataChanged;  
153    if not Modified then 
154       FModified := True;  
155  end;  
156    
157  procedure TBrokerDataSource.SetBrokerFieldList(const Value: TBrokerFieldList);  
158  begin 
159    FBrokerFieldList := Value;  
160  end;  
161    
162  function TBrokerDataSource.GetDataSource: TDataSource;  
163  begin 
164   Result := FDataSource;  
165  end;  
166    
167  procedure TBrokerDataSource.SetDataSource(const Value: TDataSource);  
168  begin 
169    FDataSource := Value;  
170    FDataSource.OnDataChange := DataChange;  
171  end;  
172    
173  { TBrokerField} 
174  procedure TBrokerField.SetFieldName(const Value: String);  
175  begin 
176    FFieldName := Value;  
177  end;  
178    
179  { TBrokerFieldList } 
180  function TBrokerFieldList.Add: TBrokerField;  
181  begin 
182    Result := TBrokerField(inherited Add);  
183  end;  
184    
185  function TBrokerFieldList.GetItems(Index: Integer): TBrokerField;  
186  begin 
187    Result := TBrokerField(inherited GetItem(Index))  
188  end;  
189    
190  procedure TBrokerFieldList.SetItems(Index: Integer; const Value: TBrokerField);  
191  begin 
192   inherited SetItem(Index, Value);  
193  end;  
194    
195  end. 
Использовать его просто
объявляете переменну класса в нужном месте 
1  Broker : TBrokerDataSource; 
далее связываете  cxVirtualVerticalGrid c данным брокером и БД
1  Broker.DataSource := <DataSource талицы БД>;  
2  cxVirtualVerticalGrid.DataController.CustomDataSource := Broker; 
после чего заполняете отображаемые колонки в cxVirtualVerticalGrid-е
с помощью функции  AddFieldBroker, в которую передаете поле БД для отображения 
сама процедура
01  procedure AddFieldBroker(var VirtualVerticalGrid: TcxVirtualVerticalGrid;  
02                                  var DataSourceBroker : TBrokerDataSource;  
03                                  RowParent : TcxCustomRow;  
04                                  Field: TField);  
05  var 
06    BrField : TBrokerField;  
07  begin 
08    BrField:= DataSourceBroker.Fields.Add;  
09    BrField.FieldName := Field.FieldName;  
10    with VirtualVerticalGrid do 
11    begin 
12       with AddChild(RowParent, TcxEditorRow) as TcxEditorRow do 
13       begin 
14        Properties.Caption := Field.DisplayName;  
15        Properties.HeaderAlignmentHorz := taLeftJustify;  
16        case Field.DataType of 
17             ftBoolean              :  
18               Properties.DataBinding.ValueTypeClass := TcxBooleanValueType;  
19             ftDate, ftDateTime, ftTime  
20                                    :  
21               Properties.DataBinding.ValueTypeClass := TcxDateTimeValueType;  
22             ftFloat,ftExtended,ftSingle  :  
23               Properties.DataBinding.ValueTypeClass := TcxFloatValueType;  
24             ftFMTBcd, ftBCD        :  
25               Properties.DataBinding.ValueTypeClass := TcxFMTBcdValueType;  
26             ftInteger, ftAutoInc, ftShortint  
27                                    :  
28               Properties.DataBinding.ValueTypeClass := TcxIntegerValueType;  
29             ftLargeint,ftLongWord  :  
30               Properties.DataBinding.ValueTypeClass := TcxLargeIntValueType;  
31             ftObject               :  
32               Properties.DataBinding.ValueTypeClass := TcxObjectValueType;  
33             ftSmallint,ftByte      :  
34               Properties.DataBinding.ValueTypeClass := TcxSmallintValueType;  
35             ftTimeStamp, ftOraTimeStamp :  
36               Properties.DataBinding.ValueTypeClass := TcxSQLTimeStampValueType;  
37             ftVariant              :  
38               Properties.DataBinding.ValueTypeClass := TcxVariantValueType;  
39             ftWideString           :  
40               Properties.DataBinding.ValueTypeClass := TcxWideStringValueType;  
41             ftString, ftFixedChar  :  
42               Properties.DataBinding.ValueTypeClass := TcxStringValueType;  
43             ftCurrency             :  
44               Properties.DataBinding.ValueTypeClass := TcxCurrencyValueType;  
45             ftWord                 :  
46               Properties.DataBinding.ValueTypeClass := TcxWordValueType;  
47        end;  
48       end;  
49    end;  
50  end; 
Пример заполнения представлен ниже (взято с реального проекта)
01  var 
02  Row : TcxCustomRow;  
03  begin 
04     
05  Broker := TBrokerDataSource.Create;  
06  Broker.DataSource := DsContract;  
07  cxVirtualVerticalGrid.DataController.CustomDataSource := Broker;  
08    
09  Row := nil;  
10  with cxVirtualVerticalGrid do 
11  begin 
12   Row := Add(TcxCategoryRow);  
13   TcxCategoryRow(Row).Properties.Caption := 'Данные регистрации';  
14  end;<  
15    
16  // поля - строки вcxVirtualVerticalGrid   
17  AddFieldBroker(cxVirtualVerticalGrid, Broker, Row, ContractNUM_REGISTRATION);  
18  AddFieldBroker(cxVirtualVerticalGrid, Broker, Row, ContractDATE_REGISTRATION);  
19  AddFieldBroker(cxVirtualVerticalGrid, Broker, Row, ContractUSER_NAME); 
И вуаля - готово, можно пользоватся

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


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

Магазин программного обеспечения   WWW.ITSHOP.RU
DevExpress / ASP.NET Subscription
DevExpress / Universal Subscription
VCL Subscription
DevExpress / DXperience Subscription
Oracle Data Access Components (ODAC) Standard Subscription - single license
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Новости ITShop.ru - ПО, книги, документация, курсы обучения
Программирование на Microsoft Access
CASE-технологии
СУБД Oracle "с нуля"
Компьютерная библиотека: книги, статьи, полезные ссылки
Windows и Office: новости и советы
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
Обсуждения в форумах
Пишу программы на заказ профессионально (2431)
Пишу программы на заказ на языках Pascal (численные методы, списки, деревья, прерывания) под...
 
Пишу программы на заказ для студентов (192)
Пишу для студентов на с, с++, паскаль в средах ms visual studio, qt, builder, borland c, delphi....
 
Excell не печатает :-( (2)
Почему то Excell не печатает страницы в альбомной ориентаций, то есть страница в аольбомной...
 
Пишу программы на заказ (1)
Пишу на языках C#, VB.NET, VBA с использованием WPF, WCF, SQL.
 
Программист для удалённой работы (ASP.NET MVC, C#, MSSQL, AJAX) (2)
предлагаю услуги по разработке web-приложений с использованием таких технологий, как: ASP.NET...
 
 
 



    
rambler's top100 Rambler's Top100