![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
TCollection. run-time VS desine-time
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?