Форум: "Компоненты";
Текущий архив: 2007.08.19;
Скачать: [xml.tar.bz2];
ВнизTCollection. run-time VS desine-time Найти похожие ветки
← →
DevilDevil © (2006-09-26 14:32) [0]Программирую таблицу. Есть свойство
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-09-26 14:35) [1]sorry за опечатку в тегах
← →
DimaBr (2006-09-26 15:11) [2]не видно конструктора и описания класса.
1. что раньше - создаётся коллекция или назначаютсяколичество столбцов ?
2. что раньше в published Column или ColsCount ?
> Теобходимо написать редактор столбцов.
?????
← →
DevilDevil © (2006-09-26 15:18) [3]> Теобходимо написать редактор столбцов.
?????
Необходимо иметь возможность в дизайн-тайм изменять Title, Width и др свойства столбца.
> 1. что раньше - создаётся коллекция или назначаются количество столбцов ?
конструктор коллекции выполняется в конструкторе таблицы. Количество столбцов назначается... при изменении published свойства Таблица.ColsCount
> 2. что раньше в published Column или ColsCount ?
ColsCount
← →
DimaBr (2006-09-26 16:24) [4]
> Необходимо иметь возможность в дизайн-тайм изменять Title,
> Width и др свойства столбца.
Для этого достаточно иметь published свойтство типа TCollection, тогда в инспекторе у этого свойства появится "..." с окном для редактирования коллекции. Если вы хотите изменять ReadOnly свойство ColCount, то я бы написал так
fColumns: TCollection;
property Columns: TCollection read fColumns write fColumns;
property ColCount: integer read GetColCount write SetColCount;
function TForm1.GetColCount: integer;
begin
Result := fColumns.Count;
end;
procedure TForm1.SetColCount(const Value: integer);
begin
while ColCount < Value do Columns.Add;
while ColCount > Value do Columns.Delete(ColCount-1);
end;
← →
DevilDevil © (2006-09-27 15:33) [5]В приведённом тобой случае, что сохраниться в dfm и в каком порядке будет работать?
← →
DimaBr (2006-09-27 15:46) [6]
private
fColumns: TCollection;
published
property Columns: TCollection read fColumns write fColumns;
property ColCount: integer read GetColCount write SetColCount;
и не дай бог наоборот
← →
DevilDevil © (2006-09-27 15:49) [7]А почему "
write fColumns
" а неSetColumns
?
← →
DimaBr (2006-09-27 16:05) [8]Можно и SetColumns
← →
DevilDevil © (2006-09-27 16:14) [9]непонятно. Чтобы все столбцы загрузились (т.е. были созданы, инициализированы свойства
Width
иTitle
) ищз dfm, вроде необходимо использоватьTCollection.Assign()
.
Недопонимаю... Недопонимаю.......
← →
DimaBr (2006-09-27 16:19) [10]Попробуйте оба варианта, потом расскажете где собака порылась.
← →
DevilDevil © (2006-09-27 16:29) [11]мммм.....
Что и в какой последовательности должно следовать, чтобы все столбцы создались и инициализировались, чтобы свойствоColsCount
тоже работало?
В каких случаях следует использовать, а в каких нетSomeObject.Assign()
? Чё то я запутался уже...
← →
DevilDevil © (2006-09-27 17:19) [12]Разве может быть такое???
У коллекции перекрываю методыAdd
иDelete
, в которых вписываюShowMessage()
с аргументами"Add"
и"Delete"
соответственно. При добавлении и удалении элементов коллекции в дизайнере, никакихShowMessage
не вызывается. Из-за чего такое происходит?
P.S. Компонент перекомпилирован
← →
DevilDevil © (2006-09-27 18:23) [13]Когда коллекция грузится из dfm, она вызывает метод
Add
? Если да, то свойствоColsCount
сохранять не надо - т.к. оно само примет нужное значение при загрузке dfm.
← →
DimaBr (2006-09-28 08:47) [14]
> У коллекции перекрываю методы Add и Delete,
Методы не виртуальны, как вы умудрились их перекрыть ?
> свойство ColsCount сохранять не надо
В принципе правильно.
← →
DevilDevil © (2006-09-28 15:22) [15]> DimaBr (28.09.06 08:47) [14]
> Методы не виртуальны, как вы умудрились их перекрыть ?
ммм... в Си нет директивы override, там это делается автоматически (если естественно метод виртуальный).
А как тогда мне перехватить и правильно отреагировать на изменения коллекции в дизайнере?
P.S. Дима, во - первых мы с Вами тёски, во - вторых Вы может быть старше меня... Может всё таки на "ты" ? :)
← →
DimaBr (2006-09-28 15:32) [16]В коллекции есть методы
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;
которые и можно перекрыть
← →
DimaBr (2006-09-28 15:36) [17]То есть пишем свою коллекцию
TMyCollection = class(TOwnedCollection)
protected
procedure Update(Item: TCollectionItem);override;
end;
procedure TMyCollection.Update(Item: TCollectionItem);
begin // возникает при изменении элемента коллекции в инспекторе
end;
и тогдаfColumns := TMyCollection.Create(self,TMyCollectionItem);
← →
DevilDevil © (2006-09-28 16:45) [18]перекрываю метод
Added
, вписываюShowMessage("Added");
Достаточно странно: при добавлении,ShowMessage
вызывается дважды. Аналогично в Ран-Тайм; при загрузке приложения, на три колонки - 6 вызововShowMessage
. Почему?
Как отследить, присвоено свойство при загрузке dfm или нет?
Позорный вопрос: за что отвечает директива deprecated ?
← →
Ketmar © (2006-09-28 16:51) [19]"deprecated" -- "устаревшее".
← →
DimaBr (2006-09-28 16:56) [20]
> Как отследить, присвоено свойство при загрузке dfm или нет?
не понял
deprecated - говорит о том, что использованая функция объявлена как устаревшая и рекомендуется использовать что-то новое
← →
DevilDevil © (2006-09-28 17:50) [21]> Как отследить, присвоено свойство при загрузке dfm или нет?
> не понял
Ну смотри. При вызовеAdded
я должен произвести некоторые действия с оперативной памятью, добавить столбец, перерисовать таблицу.
Незнаю почему [ :) ], но мне не хочется перерисовывать таблицу, если свойство присвоено (или вызван метод,Added
, например) в момент загрузки dfm. Таких загрузок много. На данный момент выполняется минимум 27 лишних перерисовок таблицы.
Почему методAdded
дублируется?
← →
DevilDevil © (2006-09-28 20:15) [22]АААЛЕЕЕЛУУУЯЯ, ААЛЕЛУУУУЯ, АЛЕЕЕЕЛУЯ, АЛЕЛУЯ, АЛЕЛУЯ...
TCollection.Notify:begin
case (Action) of:
cnAdded : MyAdding(Item);
cnExtracting, cnDeleting : MyDeleting(Item->Index);
end;
end;
...таким банальным образом отлавливаю события добавления и удаления ...
← →
DimaBr (2006-09-29 08:48) [23]Для уменьшения количества отрисовок используем BeginUpdate - EndUpdate
← →
DevilDevil © (2006-10-02 15:46) [24]Снова вопросы.
Создал пока 2 свойства:Title : string
иWidth : integer;
Примечательно то, что если изменить эти своства вObject Inspector
-е, то всё корректно сохранится в dfm. ЕслиObject Inspector
не использовать, то свойство не сохраняется.
Допустим ширина первого столбца равна 20 пикселей. Мышью изменяю ширину столбца до ста двадцати пикселей, запускаю - ширина почему-то равна 20 пикселей. Смотрю вObject Inspector
; написано120
. Запускаю - опять 20. Опять захожу в Инспектор, кликаю в полеWidth
, нажимаю Enter, запускаю... Всё работает правильно...
Вопрос: Как заставить сохраниться в dfm?
Вопрос №2: При клике в шапке столбца, соответсвующий столбец должен открыться в Инспекторе Объектов. Как это реализовать?
← →
DimaBr (2006-10-02 16:20) [25]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 18:05) [26]ВСЕМ спасибо ОГРОМНОЕ. В частности ДимеБр !!!
Вроде всё работает как надо...
Страницы: 1 вся ветка
Форум: "Компоненты";
Текущий архив: 2007.08.19;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.046 c