Форум: "Базы";
Текущий архив: 2003.11.13;
Скачать: [xml.tar.bz2];
ВнизDBAware Controls Найти похожие ветки
← →
Val (2003-10-14 14:17) [0]Коллеги, подскажите пожалуйста, как из множества контролов, находящихся, на форме, в контейнере, т.д., определить DBAware Controls и изменить у них всех одно и то же свойство?
Приведение типов при переборе вроде бы не подходит, поскольку это может быть любой DBAware Control?
← →
Vlad (2003-10-14 14:21) [1]for i:=0 to form1.ComponentsCount-1 do
begin
if Components[i] is TDBEdit then with TDBEdit(Components[i]) do...
if Components[i] is TDBCombobox then with TDBCombobox(Components[i]) do...
....
end;
← →
dmtr (2003-10-14 14:21) [2]Помойму у DB контролов обязательно есть свойство DataSource. Поэтому, пробегись в цикле по всем контролам и у кого есть это свойство, тот тебе и нужен.
← →
Val (2003-10-14 14:28) [3]это понятно, я и говорю, что не хочется делать такое приведение для всех DBAware классов - как-то не по-человечески...
← →
Danilka (2003-10-14 14:28) [4][2] dmtr © (14.10.03 14:21)
а как узнать, есть ли у компонента MyComp, который является экземпляром класса TMyComp, свойство DataSource или нет?
← →
Val (2003-10-14 14:29) [5]Danilka © (14.10.03 14:28) [4]
MyComp.FieldAddress("DataSource") <> nil ?
← →
Vlad (2003-10-14 14:36) [6]Ну и что, у TQuery тоже есть DataSource, хотя он не является контролом.
В любом случае придется цикл писать. Но тогда уж не ComponentCount, а ControlCount. И процедура будет рекурсивной.
← →
dmtr (2003-10-14 14:38) [7]function IsDataSource(Comp: TComponent): Boolean;
var
PropInfo: PPropInfo;
begin
PropInfo := GetPropInfo(Comp.ClassInfo, "DataSource");
Result := PropInfo <> nil;
if Result then
if not (PropInfo^.Proptype^.Kind = tkClass) and
(GetTypeData(PropInfo^.PropType^).ClassType.InheritsForm(TDataSource))) then
Result := False;
end;
← →
jack128 (2003-10-14 14:41) [8]
> dmtr © (14.10.03 14:38) [7]
уточнение ;-) uses TypInfo;
← →
Val (2003-10-14 14:43) [9]да, да, ControlCount, не в этом проблема - как им всем свойство поменять? Ведь это могут быть какие_угодно контролы, как стандартные, так и другие - это формочка, которую я пишу, будет неким предком для других форм проекта, на которой в зависимости от ее состояния (browse,insert,edit) нужно изменять ReadOnly у DBAware Controls.
← →
dmtr (2003-10-14 14:44) [10]Да, еще в Uses добавь TypInfo и вместо InheritsForm напиши InheritsFrom
← →
dmtr (2003-10-14 14:46) [11]Вот полный вариант
uses TypInfo, DB;
function IsDataSource(Comp: TComponent): Boolean;
var
PropInfo: PPropInfo;
begin
PropInfo := GetPropInfo(Comp.ClassInfo, "DataSource");
Result := PropInfo <> nil;
if Result then
if not ((PropInfo^.Proptype^.Kind = tkClass) and
(GetTypeData(PropInfo^.PropType^).ClassType.InheritsFrom(TDataSource))) then
Result := False;
end;
← →
Vlad (2003-10-14 14:47) [12]Ну и что, в цикле проходишь по всем контролам (именно контролам, а не компонентам) и смотришь, есть ли у них DataSource c помощью ф-ции dmtr © (14.10.03 14:38) [7]
Только имей ввиду, что форма - это иерархическая структура, так что цикл должен быть рекурсивным.
← →
Val (2003-10-14 14:55) [13]как это, что?
property Controls[Index: Integer]: TControl;
откуда я возьму у TControl свойство ReadOnly, скажем?
← →
Vlad (2003-10-14 15:11) [14]Лучше не парься, и сделай как я говорил в [1]
Перебрать все DB компоненты не сложно. Их не так много.
← →
Val (2003-10-14 15:20) [15]>Vlad © (14.10.03 15:11) [14]
нет, надо париться, потому что это может быть контрол и из RX и из Ehlib и из еще-черт-знает-откуда...
>All
Вопрос открыт. Ткните в ссылки по теме, пожалуйста.
← →
Danilka (2003-10-14 15:28) [16][15] Val © (14.10.03 15:20)
Универсального никак не сделаешь: т.к., можно сделать DBAware компонент, который-бы не имел свойства ReadOnly, и даже не имел-бы свойства DataSource, или имел-бы, но оно называлось по-другому.
Кроме того, зачастую, в зависимости от состояний требуется менять состояния не только DBAware компонент, но и enable кнопок, например, и других компонент, которые вообще никакого отношения к DB не имеют.
А в чем проблема вручную в обработчиках нужных событий изменить свойства только того, что надо?
← →
Val (2003-10-14 15:40) [17]>Danilka © (14.10.03 15:28) [16]
1.возможно..но это теория.
2.согласен, но с кнопками и т.д. - другая история - можно менять состояния контейнеров, скажем, панелей, на которых они находятся, это не так заботит.
3. На формах-наследниках м.б. любое количество любых контролов, скажем в зависимости от полей отображаемого НД, в каждой форме и каждом контроле менять...или я не понял идеи?
← →
Danilka (2003-10-14 15:47) [18][17] Val © (14.10.03 15:40)
Если форма - предок для других форм, то сделать у нее события OnBrowse, OnInsert, OnEdit, а наследники, могут в обработчиках этих событий изменять состояния своих контролов как им надо.
← →
Val (2003-10-14 16:08) [19]>Danilka © (14.10.03 15:47) [18]
с событиями ясно, но с контролами так нехорошо :(
← →
Val (2003-10-16 11:06) [20]Тем кому интересно: вопрос решался довольно просто с помошью RTTI. Думаю, писателям компонентов не составило бы никакого труда на него ответить.
Вот код из 2-го тома Пачеки,Тейксейры:
Определяем, что компонент имеет свойство "DataSource", на основании чего сходимся на том, что это DBAware Component.
function IsDBAware(AComp: TComponent): Boolean;
var
PropInfo: PPropInfo;
begin
PropInfo := GetPropInfo(AComp.ClassInfo, "DataSource");
Result := PropInfo <> nil;
if Result then
if not ((PropInfo^.Proptype^.Kind = tkClass) and
(GetTypeData(PropInfo^.PropType^).ClassType.InheritsFrom(TDataSource))) then
Result := False;
end;
А вот так устанавливаем то самое, несчастное "ReadOnly":
procedure SetBooleanPropertyIfExists(AComp: TComponent; APropName: String;
AValue: Boolean);
var
PropInfo: PPropInfo;
begin
PropInfo := GetPropInfo(AComp.ClassInfo, APropName);
if PropInfo <> nil then
begin
if PropInfo^.PropType^.Kind = tkEnumeration then
SetOrdProp(AComp, PropInfo, Integer(AValue));
end;
end;
Всем спасибо, вопрос закрыт.
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2003.11.13;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.029 c