Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Общий тип для манипуляции несовместимыми типами с общими свойств. [D7, XP, 2003]


Страницы:   1 2 3

Дмитрий ©   (2014-03-05 17:40:00) 

Хочу сделать универсальный объект, который позволили бы единобразно обращаться к некоторым общим свойствам гридов разных типов.
В частности в проекте встречаются  одновременно DBGrid, RxDBGrid, DBGridEh.
Для реализации нужной функциональности сетки нужно обращаться к свойствам DataSource, OnFilter... и т.д., которые имеются у всех этих типов.
Возможно ли сделать объект или приведение типа, чтобы можно было привязывать любой тип сетки
вроде UniGrid.DataSource:=...


Дмитрий   (2014-03-21 17:41:00) [21]

Странный вопрос.
Можно и левое ухо правой рукой чесать.
Но мы же не обязаны пользоваться этой возможностью.

Мне нужна прослойка между гридом и датасетом, реализующая отсутствующий функционал.
И возможность подложить эту прокладку под часто используемые гриды и датасеты.
И все это обернуть функцией создания и отображения типовой формы.

С датасетами проще есть общий тип.
С гридами проблема.


clickmaker   (2014-03-21 17:24:00) [22]

> создание типовой формы для просмотра таблиц или выбора значений
> из таблиц

и в этой форме могут быть использованы все эти виды гридов?


Дмитрий   (2014-03-21 17:14:00) [23]

Проект обычный.
Где со временем пришлось добавлять функционал.
В частности, отображение мемо и "заморозку столбцов", которые вызвали переход на ЕхЛиб.
Кроме этого, хочу иметь "свободу выбора гридов" для других проектов.
Итоговый результат - создание типовой формы для просмотра таблиц или выбора значений из таблиц с сортировкой и фильтром при помощи пары строк кода.


clickmaker   (2014-03-21 16:53:00) [24]

что ж это за проект, где целая толпа гридов заюзана? )


Дмитрий   (2014-03-21 16:45:00) [25]

У меня в любом случае класс-адаптер, что с РТТИ, что без.
Как без прямого указания типа сделать класс-адаптер?

Вариант с прямым указанием и приведением типа
if (self.Grid is TDBGridEh) then  
result:=(self.Grid as TDBGridEh).DataSource;

не очень нравится тем, что для привязки еще одного типа, например Jedi-грида придется править все процедуры и функции.


clickmaker   (2014-03-21 16:32:00) [26]

> [25] Дмитрий   (21.03.14 16:09)

тебе уже ответили. К published можно через RTTI
к не-published - как вариант - через свой класс-адаптер


Дмитрий   (2014-03-21 16:09:00) [27]

Как мне обратиться к известным свойствам и полям объекта заранее неизвестного типа?


Германн   (2014-03-21 02:08:00) [28]


> Дмитрий   (20.03.14 19:58) [22]
>
> Подозреваю ехидство.

Правильно подозреваешь.
Но это не совсем ехидство. На сём форуме многие авторы вопросов пытались добиться желаемого результата методом тыка. Но только одного я знаю, который добился.
Но даже он/она имел гораздо более высокий уровень базовых знаний, чтобы не пытаться использовать функции/процедуры, которые явно относятся к другой теме.


clickmaker   (2014-03-20 21:50:00) [29]

> [22] Дмитрий   (20.03.14 19:58)

grid.FindComponent ищет среди компонентов, владельцем которых является grid.
SelectedField - это по сути вычисляемое свойство, которое указывает на одно из полей источника данных в контексте текущей записи.


Дмитрий   (2014-03-20 19:58:00) [30]

Подозреваю ехидство.
Вы можете подсказать поконкретнее?


Германн   (2014-03-20 17:51:00) [31]


> Попробовал через FindComponent
> Тоже не сработало.

Не расстраивайся. В Дельфи еще много функций начинающихся словом Find. Авось какая-нибудь из них сработает. Продолжай пробовать.


Дмитрий   (2014-03-20 17:20:00) [32]

Как тогда быть?
Попробовал через FindComponent

//  obj := (self.grid as TComponent).FindComponent('SelectedField');
 obj := self.grid.FindComponent('SelectedField');
 if (obj is TField) then
   result:=TField(obj);

Тоже не сработало.


icWasya   (2014-03-20 17:13:00) [33]

через GetObjectProp можно достать только published-property


Дмитрий   (2014-03-20 16:49:00) [34]

Пытаюсь добраться до поля SelectedField грида Grid - поле типа TObject, где хранится ссылка на объект типа TDBGridEh (передаю в тестовом примере).

function TFindExt.GetSelectedField : TField;
var
 obj : TObject;
begin
 result:=nil;
//1- не срабатывает, выдает сообщение "свойство не найдено" и выходит из процедуры}
 obj :=GetObjectProp(Grid,  'SelectedField'); //
 if (obj is TField) then
   result:=TField(obj);

//2-работает, возвращает ожидаемое значение
 if (self.Grid is TDBGridEh) then
   result:=TDBGridEh(self.Grid).SelectedField;
end;

Почему не срабатывает GetObjectProp?


Дмитрий   (2014-03-06 20:44:00) [35]

С обработчиком получилось, вот таким методом

procedure SetObjectMetod(DestinObj : TObject; RemoveMetod: string; SourceObj : TObject; AlterMetod : string);
var
 PropInfo: PPropInfo;
 CommonMethod: TMethod;
begin
   PropInfo := GetPropInfo( DestinObj.ClassInfo, RemoveMetod);
   if PropInfo <> nil then
   begin
     CommonMethod.Data := SourceObj;
     CommonMethod.Code := SourceObj.MethodAddress(AlterMetod);
     SetMethodProp( DestinObj, PropInfo, CommonMethod );
   end;
end;
...
//вызов
 SetObjectMetod(Grid, 'OnKeyPress', Self, 'KeyPress');
...


Дмитрий   (2014-03-06 17:38:00) [36]

Хотелось бы что-то вроде
SetProp(Object, 'DataSource', DataSource);
SetProp(Object, 'OnKeyPress', KeyPress);
или
Object.Prop('DataSource'):= DataSource;
Object.Prop(''OnKeyPress'):= KeyPress;
Чтобы в результате были заполнены поля переданного объекта в не зависимости TDBGridEh это или TRxDBGridEh


Inovet   (2014-03-06 15:43:00) [37]

> [13] Дмитрий   (06.03.14 15:19)

> [14] Дмитрий   (06.03.14 15:28)

Первое и оставь


Дмитрий   (2014-03-06 15:28:00) [38]

и так

 if (Grid.ClassName='TDBGrid')
   or (Grid.ClassName='TDBGridEh')
   or (Grid.ClassName='TRxDBGrid')
 then  begin
   self.Grid:=TSomeGrid(Grid);
   Create(self.DataSource.DataSet); //DataSource - проперть
//    self.Grid.OnKeyPress:= KeyPress;


Дмитрий   (2014-03-06 15:19:00) [39]

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

Перед тем как по-простому, в лоб, приводить типы, делал так

 if (self.Grid is TDBGridEh) then  
result:=(self.Grid as TDBGridEh).DataSource;
 if (self.Grid is TDBGrid) then  
result:=(self.Grid as TDBGrid).DataSource;
 if (self.Grid is TRxDBGrid) then    
result:=(self.Grid as TRxDBGrid).DataSource;

Была надежда на возможность сократить.


Юрий Зотов   (2014-03-06 09:05:00) [40]

> Дмитрий   (06.03.14 02:36) [9]

> После применения
> dbgc:= TCustomDBGrid(dbgeh) ;
> возникли разные интересные эффекты


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

> как добиться нужного эффекта через RTTI?

См. исходники модуля TypInfo. Там куча полезных функций, которые позволяют работать со свойствами через их имена.

Но и это может не помочь. Например, если в двух классах одно и то же по сути свойство имеет разные имена, то Ваша задумка не прокатит. Поэтому присоединяюсь к [11].


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо