Форум: "Компоненты";
Текущий архив: 2005.11.20;
Скачать: [xml.tar.bz2];
ВнизРазные классы, в колекции Найти похожие ветки
← →
Mim2 (2005-03-17 16:10) [0]Я как понимаю такое нереально, так как в конструктор колекции мы передаем ссылку на класс итема коллекции. Именно поэтому как я понимаю для полей датасета создали свой редактор (там поля tstringfiled, tintegerfield и т.д.). Или я ошибаюсь?
← →
Юрий Зотов © (2005-03-17 16:27) [1]Нереально, конечно. Все элементы коллекции имеют один класс. Иначе как, например, смог бы работать метод Add?
А поля датасета к коллекциям отношения не имеют. Поля - это невидимые компоненты, которые хотя и не видны, но реально присутствует на форме, датасет только содержит их список. Ну а поскольку они не видны, то для работы с ними нужен редактор.
← →
jack128 © (2005-03-17 17:50) [2]Юрий Зотов © (17.03.05 16:27) [1]
Все элементы коллекции имеют один класс
function TSameCollection.Add: TCollectionItem;
var
cl: TCollectionItemClass;
begin
cl := nil;
if Assigned(FOnGetCollectionItemClass) then
FOnGetCollectionItemClass(Self, cl);
if not Assigned(cl) then
raise Exception.Create("Задайте класс элемента коллекции");
Result := cl.Create(Self);
end;
← →
Юрий Зотов © (2005-03-17 18:02) [3]> jack128 © (17.03.05 17:50) [2]
Это очевидно. Но не реализовано.
← →
vuk © (2005-03-17 18:41) [4]to Юрий Зотов © (17.03.05 16:27) [1]:
>Все элементы коллекции имеют один класс.
Судя по исходникам, получается немного не так. Элементы коллекции должны быть унаследованы от одного класса (того, который задан коллекции при конструировании). Если нужно добавить в коллекцию экземпляр класса, который унаследован от класса заданного при конструировании, но не является им, можно пользоваться методом Create класса TCollectionItem.
constructor TCollectionItem.Create(Collection: TCollection);
begin
SetCollection(Collection);
end;
procedure TCollectionItem.SetCollection(Value: TCollection);
begin
if FCollection <> Value then
begin
if FCollection <> nil then FCollection.RemoveItem(Self);
if Value <> nil then Value.InsertItem(Self);
end;
end;
procedure TCollection.InsertItem(Item: TCollectionItem);
begin
if not (Item is FItemClass) then TList.Error(@SInvalidProperty, 0);
FItems.Add(Item);
Item.FCollection := Self;
Item.FID := FNextID;
Inc(FNextID);
SetItemName(Item);
Notify(Item, cnAdded);
Changed;
NotifyDesigner(Self, Item, opInsert);
end;
Как видно, проверка типа вставляемого элемента производится при помощи is, а не простым сравнением, что позволяет добавлять в коллекцию элементы разных классов.
← →
vuk © (2005-03-17 18:41) [5]>методом Create
Конструктором, конечно же.
← →
Юрий Зотов © (2005-03-17 18:52) [6]> vuk © (17.03.05 18:41) [4]
Да, так, конечно, точнее.
← →
Набережных С. © (2005-03-17 20:03) [7]
> vuk © (17.03.05 18:41) [4]
Что-то я не понял:( Как можно воспользоваться конструктором класса элемента коллекции (того класса, который передан в конструктор коллекции) для добавления в коллекцию элементов разных классов? Без кардинальной переработки всей инфраструктуры поддержки коллекций? Не, не въезжаю:( Пример можно?
← →
vuk © (2005-03-17 20:34) [8]to Набережных С. © (17.03.05 20:03) [7]:
>Пример можно?
TMyCollectionItem.Create(SomeCollection);
← →
vuk © (2005-03-17 20:43) [9]Или, если угодно, развернутый пример для компиляции.
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils, Classes;
type
TMyItem = class(TCollectionItem)
procedure DoSomething; virtual;
end;
TMyExtItem = class(TMyItem)
procedure DoSomething; override;
end;
TOtherItem = class(TCollectionItem)
procedure DoAnotherThing;
end;
procedure TMyItem.DoSomething;
begin
writeln("TMyItem.DoSomething");
end;
procedure TMyExtItem.DoSomething;
begin
writeln("TMyExtItem.DoSomething");
end;
procedure TOtherItem.DoAnotherThing;
begin
writeln("TOtherItem.DoAnotherThing");
end;
var
C: TCollection;
i: integer;
Current: TCollectionItem;
begin
C := TCollection.Create(TCollectionItem);
try
TMyItem.Create(c);
TMyExtItem.Create(c);
TOtherItem.Create(c);
for i := 0 to c.count - 1 do
begin
Current := c.Items[i];
if Current is TMyItem then
TMyItem(Current).DoSomething
else
if Current is TOtherItem then
TOtherItem(Current).DoAnotherThing;
end;
finally
C.Free;
end;
readln;
end.
← →
Набережных С. © (2005-03-17 20:51) [10]
> vuk © (17.03.05 20:34) [8]
Ну то есть чисто в ран-тайм, в обход Add. И вся инфраструктура режима дизайна побоку. Вообще-то конференция называется "Компоненты", если кто не заметил:))
← →
Набережных С. © (2005-03-17 20:55) [11]Все-таки надо ветку обновлять, перед отправкой:)
> vuk © (17.03.05 20:43) [9]
Да не обязательно было, и так все ясно. См.[10]:)))
← →
vuk © (2005-03-17 21:06) [12]to Набережных С.:
>Ну то есть чисто в ран-тайм, в обход Add.
Вообще говоря да. Все это барахло не сможет быть прочитано из потока, хотя и запишется без проблем. Это проблема стандартных коллекций. Они являются полиморфными, но файлеры не имеют поддержки этого полиморфизма.
В принципе, если сильно захотеть, можно написать свои collection-подобные классы, которые будут обеспечивать полиморфизм при загрузке, но для этого придется регистрировать загружаемые классы и поковыряться с сохранением свойств.
← →
Набережных С. © (2005-03-17 21:15) [13]
> vuk © (17.03.05 21:06) [12]
Это конечно. Плюс к тому и собственный редактор коллекции. И даже возможно, что в каком-то особом случае может появиться смысл все это сделать, но возни будет довольно много, по-моему.
← →
vuk © (2005-03-17 21:25) [14]to Набережных С. © (17.03.05 21:15) [13]:
Я такие вещи делал, правда, без designtime поддержки, но в потоках это все жило на ура. У меня мообще в полузаброшенном состоянии имеется свой набор контейнерных классов. Иногда использую, когда возможностей стандартных не хватает.
← →
Набережных С. © (2005-03-17 21:32) [15]
> vuk © (17.03.05 21:25) [14]
Да, для "внутреннего употребления" - вопроса нет, и сам делал. Я-то имел в виду возню с поддержкой режима дизайна.
← →
Cobalt © (2005-03-18 09:39) [16]А можно примерчик, когда может потребоваться в Дизайне задать разные элементы коллекции?
← →
Mim2 (2005-03-18 09:54) [17]Я в вопросе забыл оговориться что разые классы это всеже наследники некого предка задаваемого при создании колекции, рад что вы меня поняли :)...
Спасибо за развернутое обьяснение, буду писать колекции подобный класс и дизайнер для него...
> Cobalt © (18.03.05 09:39) [16]
> А можно примерчик, когда может потребоваться в Дизайне задать
> разные элементы коллекции?
Чисто теоритически можно было тотже TField пронаследовать от TCollectionItem, а уже наследники tfield типо tstringfield размещать в коллекции, это избавило бы разрабочиков (VCL) от необходимости писать свой дизайнер ...
← →
Юрий Зотов © (2005-03-18 10:48) [18]> Mim2 (18.03.05 09:54) [17]
Просто поля в VCL были сразу, а коллекции появились позже.
← →
vuk © (2005-03-18 13:51) [19]to Mim2 (18.03.05 09:54) [17]:
>Чисто теоритически можно было тотже TField пронаследовать от
>TCollectionItem
Чисто теоретически можно, но практически, как уже сказано, из потока грузиться не будет из-за механизма загрузки коллекций.
Страницы: 1 вся ветка
Форум: "Компоненты";
Текущий архив: 2005.11.20;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.043 c