Текущий архив: 2005.07.11;
Скачать: CL | DM;
ВнизУправляемое сохранение свойств компонента Найти похожие ветки
← →
far (2004-06-14 19:13) [0]Доброго времени суток, уважаемые!
Возник интересный вопрос, я надеюсь на вашу помощь.
Можно ли изменить порядок, в котором свойства компонента сохраняются в файл формы?
Мой компонент содержит несколько наборов TCollection, редактируемых в design-time. Элементы некоторых наборов логически связаны с элементами других наборов. Эту связь я осуществляю с помощью указателей.
При сохранении элемента в файл формы, я вместо указателя сохраняю текстовое свойство, однозначно идентифицирующее связанный объект.
При загрузке элемента, считывается текстовое свойство и преобразуется в указатель посредством поиска соответствующего свойству элемента в нужном наборе.
Естественно, если этот последний набор еще не прочитался мы в нем ничего не найдем. Что у меня и происходит :)
Вот и хотелось бы сохранить сначала независимые наборы, а потом уже - зависимые от них.
Если есть несложный способ, подскажите пожалуйста. Хотя я чувствую, что придется все-таки отказаться от указателей и заменить их на TCollectionItem.ID :-\
← →
pasha_golub © (2004-06-15 01:02) [1]А кусок кода мона?
← →
malkolinge © (2004-06-15 11:13) [2]TComponent.Loaded + F1
← →
far (2004-06-16 14:17) [3]Спасибо Евгений, все ясно :)
Кстати хочу похвастаться: я купил Вашу книгу. Хороший, доходчивый стиль. Но хотелось бы побольше о сложных свойствах. Вот о коллекциях тех же самых. И как следствие - об Object TreeView. Об этой гадости никакой информации вообще нигде нет.
← →
far (2004-06-16 14:25) [4]To pasha_golub:
Я думаю, что вопрос, в принципе, теоретический. Зачем тут частности?
← →
pasha_golub © (2004-06-16 18:45) [5]far (16.06.04 14:25) [4]
Я не въехал просто в постановку. :-)
← →
far (2004-06-17 15:38) [6]Ну, если упростить то выглядит примерно так:
---------------------------------------------
interface
TMyCollItem = class (TCollectionItem)
private
//ссылка на элемент другой коллекции
FAnother: TAnotherCollItem;
function GetAnotherName: String;
procedure SetAnotherName(const Value: String);
published
//идентификатор элемента FAnother
property AnotherName: String read GetAnotherName write SetAnotherName;
end;
implementation
function TSchemeItem.GetAnotherName: String;
begin
//получаем идентификатор элемента FAnother (он же и сохраняется в файл)
if FPointer = nil then
Result := ""
else
Result := FPointer.Name;
end;
procedure TSchemeItem.SetAnotherName(const Value: String);
var
NewAnother: TAnotherCollItem;
begin
//задаем новый указатель по идентификатору. В т.ч. при чтении из файла
NewAnother := AnotherCollection.FindItemByName(Value);
if NewAnother = nil then
Raise Exception.Create("Элемент в Another Collection не найден.");
//при чтении компонента, элементы Another Collection еще не
//прочитаются, если они записаны в файл после элементов MyCollection
FAnother := NewAnother;
end;
----------------------------------------------------------
Как правильно сказал malkolinge (надеюсь я правильно его понял), надо сначала все прочитать, а потом уже инициализировать указатели. Я сделал это так:
procedure TSchemeItem.SetAnotherName(const Value: String);
var
NewAnother: TAnotherCollItem;
begin
//-->
if csReading in GetComponentState then begin
//запоминаем AnotherName во временном наборе
TMyCollection(Collection).FTempNameList.Add(Value);
//-->
NewAnother := AnotherCollection.GetItem(Value);
if NewAnother = nil then
Raise Exception.Create("Элемент в Another Collection не найден.");
FAnother := NewAnother;
end;
После загрузки компонента, выполняем процедуру
procedure TMyCollection.InitPointers;
var
i: Integer;
begin
for i := 0 to Count-1 do begin
Items[i].AnotherName := FTempNameList[i];
end;
end;
← →
Бином Ньютоныч (2004-06-17 17:28) [7]Есть ведь директива Stored false и метод DefineProperties
← →
far © (2004-06-18 11:32) [8]Действительно, с ними можно это сделать аккуратнее, спасибо.
Но принципиально ведь ничего не меняется, правда?
← →
Igorek © (2004-06-23 13:29) [9]Имхо можно использовать именно указатели на обьекты классов. Сами классы вроде надо регистрировать. И сама ВЦЛ все сделает в финальной стадии загрузки - там что-то проде FixUp... См. ReadComponent.
← →
Некто (2004-06-23 14:08) [10]> far (14.06.04 19:13)
> хотелось бы сохранить сначала независимые наборы, а потом уже -
> зависимые от них.
> Если есть несложный способ, подскажите пожалуйста.
Такой способ есть. Как уже говорилось, можно использовать Loaded, можно - stored False + DefineProperties, но можно сделать и гораздо проще.
Как известно, свойства сохраняются в DFM в порядке их объявления в секции published, а читаются в порядке сохранения (то есть, в том же самом). Значит, для решения Вашей задачи достаточно просто-напросто изменить порядок объявления свойств - сначала объявить коллекции с независимыми элементами, а потом - с зависимыми.
При этом текстовые свойства элементов коллекций (которые Вы преобразуете в указатели) будут считываться уже после чтения независимых элементов - что и требовалось. Само преобразование нужно выполнять в методах Set для этих текстовых свойств.
← →
far © (2004-07-13 18:15) [11]Извините, господа, отвлекся слегка на сдачу сессии :)
Некто (23.06.04 14:08) [10]: Ну что тут сказать? Просто и гениально!
Но мне не помогло. В моем случае, одна из независимых коллекций (а именно набор Fields в TADOQuery) объявлена в предке моего компонента и далеко не мною. Да и это не коллекция вообще-то :). Как бы то ни было, сохраняется она почему-то не первой, что не вполне объяснимо. Действительно, по логике вещей сначала надо бы сохранить свойства родительского компонента...
>Igorek © (23.06.04 13:29) [9]:
>Сами классы вроде надо регистрировать.
Регистрировать? А как?
Страницы: 1 вся ветка
Текущий архив: 2005.07.11;
Скачать: CL | DM;
Память: 0.48 MB
Время: 0.044 c