Форум: "Начинающим";
Текущий архив: 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)
Тебе Датасет надо или остальные поля и свойства? Какие тогда остальные?
Страницы: 1 2 вся ветка
Форум: "Начинающим";
Текущий архив: 2015.09.10;
Скачать: [xml.tar.bz2];
Память: 0.55 MB
Время: 0.053 c