Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

TCollection. run-time VS desine-time


Страницы:   1 2

DevilDevil ©   (2006-09-26 14:32:00) 

Программирую таблицу. Есть свойство ColsCount- количество столбцов. Каждому столбцу в таблице соответствует класс TCol.

Теобходимо написать редактор столбцов.

Для реализации этого свойства [ Columns ...] использую коллекцию. Мне не хочется наследовать уже готовый TColот TCollectionItem. Поэтому я реализую "соответствие"; в моём классе-элементе коллекции в разделе publicсодержится свойство Column : TCol.

При изменении количества столбцов (свойства ColsCount) соответствующим образом должна изменяться коллекция:

void __fastcall TInfoTable::SetColsCount(int Count)
{
...>
Если, например, было 0</B, а стало Count [ 1</B например]
if (Count > FColsCount)
{
FCols.Count = Count;

for (int i = FColsCount; i < Count; i++)
{
TCol *Buf = new TCol(this);
FCols.Memory[i] = Buf;
// -->>>
FColumns->Add()->Column = Buf;
}
}
...


Так всё вроде нормально работает (кроме случаев удаления элементов коллекции в дизайнере).

Стал добавлять свойства в мой TColumnItem- потомок TCollectionItem; в частности свойство Title : string;:

void __fastcall TColumnItem::SetTitle(AnsiString S)
{
 FCol->Title = S;
}


И так всё работает [в desine-time]. Зато при запуске приложения в ран-тайм, ошибка доступа к данным. Начал трассировать, оказывается, FCol = nil. Начал трассировать дальше, оказалась вообще ерунда какая-то...   TColumnItemсначала создаётся, потом даже вызывается его деструктор, потом...

Очень прошу помощи. Что я делаю не так?


DevilDevil   (2006-10-02 18:05:00) [1]

ВСЕМ спасибо ОГРОМНОЕ. В частности ДимеБр !!!

Вроде всё работает как надо...


DimaBr   (2006-10-02 16:20:00) [2]

1. Нужно сообщить дизайнеру что произошли изменения.

при перемещении колонки
if GetParentForm(self) > nil then
 if GetParentForm(self).Designer <> nil then
   GetParentForm(self).Designer.Modified;

2. Для этого вам придётся переписать половину VCL, по крайней мере свой ТСомponent, TControl и т д. Это реализовано в DevExpress, загляните.


DevilDevil   (2006-10-02 15:46:00) [3]

Снова вопросы.

Создал пока 2 свойства: Title : stringи Width : integer;

Примечательно то, что если изменить эти своства в Object Inspector-е, то всё корректно сохранится в dfm. Если Object Inspectorне использовать, то свойство не сохраняется.

Допустим ширина первого столбца равна 20 пикселей. Мышью изменяю ширину столбца до ста двадцати пикселей, запускаю - ширина почему-то равна 20 пикселей. Смотрю в Object Inspector; написано 120 . Запускаю - опять 20. Опять захожу в Инспектор, кликаю в поле Width, нажимаю Enter, запускаю... Всё работает правильно...

Вопрос: Как заставить сохраниться в dfm?

Вопрос №2: При клике в шапке столбца, соответсвующий столбец должен открыться в Инспекторе Объектов. Как это реализовать?


DimaBr   (2006-09-29 08:48:00) [4]

Для уменьшения количества отрисовок используем BeginUpdate - EndUpdate


DevilDevil   (2006-09-28 20:15:00) [5]

АААЛЕЕЕЛУУУЯЯ, ААЛЕЛУУУУЯ, АЛЕЕЕЕЛУЯ, АЛЕЛУЯ, АЛЕЛУЯ...

TCollection.Notify:

begin

  case
(Action) of:

    cnAdded     : MyAdding(Item);
    cnExtracting, cnDeleting  : MyDeleting(Item->Index);

  end;

end;


...таким банальным образом отлавливаю события добавления и удаления ...


DevilDevil   (2006-09-28 17:50:00) [6]

> Как отследить, присвоено свойство при загрузке dfm или нет?
> не понял

Ну смотри. При вызове Addedя должен произвести некоторые действия с оперативной памятью, добавить столбец, перерисовать таблицу.

Незнаю почему [ :) ], но мне не хочется перерисовывать таблицу, если свойство присвоено (или вызван метод, Added, например) в момент загрузки dfm. Таких загрузок много. На данный момент выполняется минимум 27 лишних перерисовок таблицы.

Почему метод Addedдублируется?


DimaBr   (2006-09-28 16:56:00) [7]


> Как отследить, присвоено свойство при загрузке dfm или нет?

не понял

deprecated - говорит о том, что использованая функция объявлена как устаревшая и рекомендуется использовать что-то новое


Ketmar   (2006-09-28 16:51:00) [8]

"deprecated" -- "устаревшее".


DevilDevil   (2006-09-28 16:45:00) [9]

перекрываю метод Added, вписываю ShowMessage('Added');

Достаточно странно: при добавлении, ShowMessageвызывается дважды. Аналогично в Ран-Тайм; при загрузке приложения, на три колонки - 6 вызовов   ShowMessage. Почему?

Как отследить, присвоено свойство при загрузке dfm или нет?

Позорный вопрос: за что отвечает директива deprecated ?


DimaBr   (2006-09-28 15:36:00) [10]

То есть пишем свою коллекцию

TMyCollection = class(TOwnedCollection)
  protected
     procedure Update(Item: TCollectionItem);override;        
end;

procedure TMyCollection.Update(Item: TCollectionItem);
begin // возникает при изменении элемента коллекции в инспекторе

end;

и тогда
fColumns := TMyCollection.Create(self,TMyCollectionItem);


DimaBr   (2006-09-28 15:32:00) [11]

В коллекции есть методы

procedure Update(Item: TCollectionItem); virtual; //
procedure Added(var Item: TCollectionItem); virtual; deprecated;
procedure Deleting(Item: TCollectionItem); virtual; deprecated;
procedure Notify(Item: TCollectionItem; Action: TCollectionNotification); virtual;

которые и можно перекрыть


DevilDevil   (2006-09-28 15:22:00) [12]

> DimaBr   (28.09.06 08:47) [14]
> Методы не виртуальны, как вы умудрились их перекрыть ?


ммм... в Си нет директивы override, там это делается автоматически (если естественно метод виртуальный).

А как тогда мне перехватить и правильно отреагировать на изменения коллекции в дизайнере?

P.S.Дима, во - первых мы с Вами тёски, во - вторых Вы может быть старше меня... Может всё таки на "ты" ? :)


DimaBr   (2006-09-28 08:47:00) [13]


> У коллекции перекрываю методы Add и Delete,

Методы не виртуальны, как вы умудрились их перекрыть ?

> свойство ColsCount сохранять не надо

В принципе правильно.


DevilDevil   (2006-09-27 18:23:00) [14]

Когда коллекция грузится из dfm, она вызывает метод Add? Если да, то свойство ColsCountсохранять не надо - т.к. оно само примет нужное значение при загрузке dfm.


DevilDevil   (2006-09-27 17:19:00) [15]

Разве может быть такое???

У коллекции перекрываю методы Addи Delete, в которых вписываю ShowMessage()с аргументами 'Add'и 'Delete'соответственно. При добавлении и удалении элементов коллекции в дизайнере, никаких ShowMessageне вызывается. Из-за чего такое происходит?

P.S.Компонент перекомпилирован


DevilDevil   (2006-09-27 16:29:00) [16]

мммм.....

Что и в какой последовательности должно следовать, чтобы все столбцы создались и инициализировались, чтобы свойство ColsCountтоже работало?

В каких случаях следует использовать, а в каких нет SomeObject.Assign()? Чё то я запутался уже...


DimaBr   (2006-09-27 16:19:00) [17]

Попробуйте оба варианта, потом расскажете где собака порылась.


DevilDevil   (2006-09-27 16:14:00) [18]

непонятно. Чтобы все столбцы загрузились (т.е. были созданы, инициализированы свойства Widthи Title) ищз dfm, вроде необходимо использовать TCollection.Assign().

Недопонимаю... Недопонимаю.......


DimaBr   (2006-09-27 16:05:00) [19]

Можно и SetColumns


DevilDevil   (2006-09-27 15:49:00) [20]

А почему " write fColumns" а не SetColumns?


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо