Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2015.09.10;
Скачать: [xml.tar.bz2];

Вниз

Общий тип для манипуляции несовместимыми типами с общими свойств.   Найти похожие ветки 

 
Дмитрий   (2014-03-05 17:40) [0]

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


 
clickmaker ©   (2014-03-05 17:41) [1]

как вариант, RTTI либо класс-адаптер


 
Дмитрий   (2014-03-05 18:11) [2]

Стоило пожаловаться, как что-то получилось.
Приводить тип к TDBGrid отказывался четырьмя лапами
Объявил урезаный тип и прямо в лоб преобразовал

type
 TSomeGrid = class
 DataSource : TDataSource;
 OnKeyPress: TKeyPressEvent;
end;
...
result:=TSomeGrid(self.Grid).DataSource;
...


 
Inovet ©   (2014-03-05 19:08) [3]

> [2] Дмитрий   (05.03.14 18:11)
> Приводить тип к TDBGrid отказывался четырьмя лапами

Ну. А к TCustomDBGrid как?


 
Дмитрий   (2014-03-05 20:03) [4]

var
 dbgc: TCustomDBGrid;
 dbgeh: TDBGridEh;
begin
 dbgc:= dbgeh as TCustomDBGrid;

F9
Incompatible types: "TCustomDBGrid" and "TDBGridEh"

а если
 dbgc:= TCustomDBGrid(dbgeh) ;
то переваривает

Сейчас думаю, как мне передать грид в качестве параметра
Если опысываю метод как
TExtend.Create(Grid :TSomeGrid)
...
begin
TExtend.Create(DBGridEh1);
end;
то вызывает ошибку


 
Юрий Зотов ©   (2014-03-06 00:10) [5]

Если
Incompatible types: "TCustomDBGrid" and "TDBGridEh"
то
dbgc:= TCustomDBGrid(dbgeh) ;
делать нельзя.

Ищите общего предка для всх гридов - его и используйте.


 
Inovet ©   (2014-03-06 00:32) [6]

> [4] Дмитрий   (05.03.14 20:03)
> Incompatible types: "TCustomDBGrid" and "TDBGridEh"

Так, что-то автор EhLib говорил, что забил на DBGrid и сделал всё по-своему. Надо смотреть в описании.


 
Inovet ©   (2014-03-06 00:37) [7]

> [0] Дмитрий   (05.03.14 17:40)
> OnFilter

А это где в TDBGrid? Уверен что делаешь то, что хочешь получить?


 
Юрий Зотов ©   (2014-03-06 00:58) [8]

Сдается мне, что общий предок есть, но к DB не имеет никакого отношения. Значит, остается RTTI.


 
Дмитрий   (2014-03-06 02:36) [9]

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

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


 
Дмитрий   (2014-03-06 02:38) [10]

Общий предок TDBGrid и TDBGridEh где-то в районе TComponent;


 
Inovet ©   (2014-03-06 07:12) [11]

> [10] Дмитрий   (06.03.14 02:38)
> Общий предок TDBGrid и TDBGridEh где-то в районе TComponent;

TCustomGrid. Естественно никакого DataSource в нём нет.

Ты вот лучше скажи - для чего в одном проекте куча разных гридов? Зачем к разным прикручивать одинаковую функциональность? Если ответ - так получилось, теперь лень переделывать. То не лениться и переделать на один. Если действительно необходимо, ну тогда, как выше сказано - через RTTI проверять тип объекта и в зависимости от типа вызывать нужный метод.


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

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

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


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

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

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

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


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

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

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

 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 15:28) [14]

и так

 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;


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

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

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

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


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

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


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

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

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-20 16:49) [18]

Пытаюсь добраться до поля 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?


 
icWasya ©   (2014-03-20 17:13) [19]

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


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

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

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

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


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


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

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


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

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


 
clickmaker ©   (2014-03-20 21:50) [23]

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

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


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


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

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


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

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


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

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

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


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

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

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

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


 
clickmaker ©   (2014-03-21 16:53) [28]

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


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

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


 
clickmaker ©   (2014-03-21 17:24) [30]

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

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


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

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

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

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


 
Германн ©   (2014-03-22 03:27) [32]

Дмитрий   (21.03.14 17:41) [31]

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

Мы не обязаны. А кто тебя заставил?


 
clickmaker ©   (2014-03-23 22:04) [33]

> прослойка между гридом и датасетом

published-свойства типа DataSource, которые у всех гридов есть, можно через RTTI получить.
А под специфичные св-ва типа SelectedField все равно придется код напильником затачивать


 
KSergey ©   (2014-03-24 11:08) [34]

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

По-моему отличный и довольно производительный вариант.
Написал один раз - и забыл, т.е. занялся чем-то более полезным, чем "наведение красоты". Которое завсегда совершенно бестолковое.


 
Дмитрий   (2014-03-24 17:57) [35]


> KSergey ©   (24.03.14 11:08) [34]
> По-моему отличный и довольно производительный вариант.

Вариант отличный, главное, рабочий.
И пока единственный.
Удручает один момент: для пристежки Джедайского Грида добавки делать во все процедуры.


 
clickmaker ©   (2014-03-24 18:02) [36]

> добавки делать во все процедуры

зачем во все? недостаточно одного статического метода-хелпера?


 
Дмитрий   (2014-03-24 19:47) [37]

Что будет делать это метод?


 
clickmaker ©   (2014-03-24 19:50) [38]

[13]


 
Дмитрий   (2014-03-25 17:01) [39]

Остальные требуемые поля и свойства этот же метод будет получать?
)


 
Inovet ©   (2014-03-25 17:06) [40]

> [39] Дмитрий   (25.03.14 17:01)

Тебе Датасет надо или остальные поля и свойства? Какие тогда остальные?


 
clickmaker ©   (2014-03-26 10:45) [41]

function TGridHelper.GetProp(AGrid: TComponent; const APropName: string): TObject;
begin
 if (APropName = "DataSource") then begin
   if (AGrid is TDBGridEh) then  
     result:=(AGrid as TDBGridEh).DataSource;
   else if (AGrid is TDBGrid) then  
    result:=(AGrid as TDBGrid).DataSource;
   if (AGrid is TRxDBGrid) then    
    result:=(AGrid as TRxDBGrid).DataSource;
 end else
 if (APropName = "SelectedField") then begin
   if (AGrid is TDBGridEh) then  
     result:=(AGrid as TDBGridEh).SelectedField;
   ...
 end else
 if...
end;


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

В большей степени мне нужны поля и свойства грида.
Align, color, columns, datasource, Drawmemotext, EditActions, Enabled, EvenRowColor, FixedColor, Flat, FrozenCols, Height, Hint, Left, Name, OddRowColor, Options, ReadOnly, Tag, Visible, Width
Еще некоторые другие типа Owner-Parent и некоторые обработчики OnKeyPressed-OnDrawColumnCell

У датасетов облегчает ситуацию наличие общего совместимого типа, у гридов такого нет.

> clickmaker ©   (26.03.14 10:45) [41]
> function TGridHelper.GetProp(AGrid: TComponent; const APropName:
>  string): TObject;
> begin...

Мысль понятна-объединить в один метод.
Возможно, с точки зрения структуры и правок это будет удобно.


 
Inovet ©   (2014-03-26 17:27) [43]

> [42] Дмитрий   (26.03.14 17:20)

Какой в этом смысл, если они разные и наборы их разные? При том, что часть из перечисленного вообще-то не этими гридамиопределена и общая для всех, и доступна нормальными способами.


 
sniknik ©   (2014-03-26 18:07) [44]

> Возможно, с точки зрения структуры и правок это будет удобно.
гарантирую, это будет жутко неудобно и глючно.

сам представь, все что ты делаешь в 1 строку будешь делать в 50 ради абстрактной универсализации. да эти 50 строк, вместо одной у тебя будут "спрятаны" в объекте но зависимости в работе с ним, "внешние", останутся. и необходимость правки именно самого кода обеспечивающего "универсальность" тоже (по умолчанию, сделает кто-то новый грид и как же универсальность если его не поддержать?).


 
Дмитрий   (2014-03-26 18:29) [45]

Inovet ©   (26.03.14 17:27) [43]
Переписал из инспектора используемые свойства ЕхГрида.
Некоторые свойства, вроде SelectedField так не помню, всплывают в процессе переделки прежнего модуля.

sniknik ©   (26.03.14 18:07) [44]
Принципиального улучшения [41] не несет по сравнению с [13], кроме группировки в одном блоке.
Во многих случаях потребуется еще одно приведение типов.
Дополнительная операция может быть заметна в обаботчиках типа OnCalc или OnDrawCell


 
sniknik ©   (2014-03-27 11:50) [46]

> Принципиального улучшения
я не про разницу кода 13 vs 41, а в принципе "за идею"... любая "универсализация" чего-то настолько различного приведет к проблемам.

как пример могу привести уже набивший оскомину ADOTable, ADOQuery "универсализировавший" логику работы с ними "под BDE".
где уже этот BDE, а проблемы из-за подобного решения до сих пор есть.


 
Дмитрий   (2014-04-14 18:53) [47]

К слову, мне не обязательно требуется реализация здесь и сейчас всех свойств ДжедайГрида и прочих.
Скорее, мне нужна болванка, которая сейчас позволяет крутить ГридЕх, в которую при потребности легко добавить прочие типы.


 
Юрий Зотов ©   (2014-04-14 22:51) [48]

> Дмитрий   (14.04.14 18:53) [47]

Прошло больше месяца, а решения так и нет. Не значит ли это, что его действительно просто нет?


 
Германн ©   (2014-04-15 02:27) [49]


> Дмитрий   (14.04.14 18:53) [47]
>
> К слову, мне не обязательно требуется реализация здесь и
> сейчас всех свойств ДжедайГрида и прочих.
> Скорее, мне нужна болванка, которая сейчас позволяет крутить
> ГридЕх, в которую при потребности легко добавить прочие
> типы.

А к своему тёзке, автору EhLib не обращался?


 
Дмитрий   (2014-04-15 17:22) [50]


> Германн ©   (15.04.14 02:27) [49]
> А к своему тёзке, автору EhLib не обращался?

Нет.
То, что нужно было от ЕхГрида обходился поиском по форумам.
А спросить про универсальный коннектор не достает наглости.
Кроме меня никому не нужно.


> Юрий Зотов ©   (14.04.14 22:51) [48]
> решения так и нет. Не значит ли это, что его действительно
> просто нет?

Так-то решение есть - прописать каждое свойство ручками.
Чем потихоньку и занимаюсь, в фоновом режиме.
Отсутствует желаемое решение.
С мороженками и печеньками.
)


 
Юрий Зотов ©   (2014-04-16 12:13) [51]

> Отсутствует желаемое решение.

Его я и имел в виду. И в полноценном виде его действительно не существует (о чем здесь уже говорилось) - слишком разные компоненты.



Страницы: 1 2 вся ветка

Форум: "Начинающим";
Текущий архив: 2015.09.10;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.59 MB
Время: 0.065 c
2-1396455235
Елена
2014-04-02 20:13
2015.09.10
как убрать инициализацию ошибки MCI


2-1392826517
dehkanin
2014-02-19 20:15
2015.09.10
Как записать в таблицу БД текст объёмом свыше 2-х мегабайт?


2-1396806177
Drowsy
2014-04-06 21:42
2015.09.10
В DBGridEh есть колонка навигации (самая левая) .


15-1416794850
Кто б сомневался
2014-11-24 05:07
2015.09.10
Нужна ли синхронизация когда потоки только читают?


15-1412408657
Pavia
2014-10-04 11:44
2015.09.10
ошибка в XE5





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский