Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Компоненты";
Текущий архив: 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
14-1130239426
Жук
2005-10-25 15:23
2005.11.20
Школьная парта


3-1128449971
Piter
2005-10-04 22:19
2005.11.20
Primary Key и Unique key


1-1130407103
BFG9k
2005-10-27 13:58
2005.11.20
Использование модулей из пакетов


2-1130757080
kami
2005-10-31 14:11
2005.11.20
Службы: узнать "Вход от имени"


2-1131193537
JBL
2005-11-05 15:25
2005.11.20
Rave Reports





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский