Форум: "Основная";
Текущий архив: 2004.04.11;
Скачать: [xml.tar.bz2];
ВнизСохранение объекта в dfm Найти похожие ветки
← →
mikeflat © (2004-04-23 13:40) [0]Есть объект, например такой
TMyObject = class(TComponent)
private
FObj: TCustomObjects;
FStr: string;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property Obj: TCustomObjects read FObj write FObj;
property Str: string read FStr write FStr;
end;
у него есть published свойство Obj - объект-наследник TComponent.
Вопрос: как сохранить этот объект в формате dfm? Свойство Str сохраняется без проблем, а вот Obj - не хочет!
← →
mikeflat © (2004-04-23 13:40) [0]Есть объект, например такой
TMyObject = class(TComponent)
private
FObj: TCustomObjects;
FStr: string;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property Obj: TCustomObjects read FObj write FObj;
property Str: string read FStr write FStr;
end;
у него есть published свойство Obj - объект-наследник TComponent.
Вопрос: как сохранить этот объект в формате dfm? Свойство Str сохраняется без проблем, а вот Obj - не хочет!
← →
MBo © (2004-04-23 13:44) [1]DefineProperties
← →
MBo © (2004-04-23 13:44) [1]DefineProperties
← →
mikeflat © (2004-04-23 14:02) [2]Да понятно, что DefineProperties, а что писать в методах чтения и записи, просто WriteComponent не идет, пример из help работает только на запись - не читает, да и вообще получается коряво. Чо делать-то?
← →
mikeflat © (2004-04-23 14:02) [2]Да понятно, что DefineProperties, а что писать в методах чтения и записи, просто WriteComponent не идет, пример из help работает только на запись - не читает, да и вообще получается коряво. Чо делать-то?
← →
oso (2004-04-23 14:44) [3]По умолчанию св-ва типа компонент (в отличие от простых
персистентов) рассматриваются как
ссылки на внешние компоненты и сохраняются в виде имён.
В Д6 появился специальный флаг csSubComponent,
позволяющий сохранять дочерние компоненты,
сохраняя все их св-ва (см SetSubComponent).
С помощью DefineProperties это так просто не сделаешь, -
парсер не переварит (Если установлен режим текстовой ДФМ).
Можно, конечно, сохранять вс-ва по одному или DefineBinaryProperties, но это всё геморрой.
Попробуй SetSubComponent, если версия позволяет.
← →
oso (2004-04-23 14:44) [3]По умолчанию св-ва типа компонент (в отличие от простых
персистентов) рассматриваются как
ссылки на внешние компоненты и сохраняются в виде имён.
В Д6 появился специальный флаг csSubComponent,
позволяющий сохранять дочерние компоненты,
сохраняя все их св-ва (см SetSubComponent).
С помощью DefineProperties это так просто не сделаешь, -
парсер не переварит (Если установлен режим текстовой ДФМ).
Можно, конечно, сохранять вс-ва по одному или DefineBinaryProperties, но это всё геморрой.
Попробуй SetSubComponent, если версия позволяет.
← →
mikeflat © (2004-04-23 16:42) [4]Но ведь сама форма все красиво сохраняет!
← →
mikeflat © (2004-04-23 16:42) [4]Но ведь сама форма все красиво сохраняет!
← →
oso (2004-04-23 16:59) [5]Там совсем другая схема сохранения.
Компоненты сохраняются не как паблишед-свойства,
а как дочерние компоненты своими родителями.
Причём при загрузке из ДФМ компоненты всегда создаются
(За исключением визуального наследования - ffInheritance),
а у тебя надо загрузить св-ва уже созданного компонента.
← →
oso (2004-04-23 16:59) [5]Там совсем другая схема сохранения.
Компоненты сохраняются не как паблишед-свойства,
а как дочерние компоненты своими родителями.
Причём при загрузке из ДФМ компоненты всегда создаются
(За исключением визуального наследования - ffInheritance),
а у тебя надо загрузить св-ва уже созданного компонента.
← →
Матлабист (2004-04-23 18:01) [6]TCustomObjects должен быть порожден от TPersistent. Иначе --- define properties
← →
Матлабист (2004-04-23 18:01) [6]TCustomObjects должен быть порожден от TPersistent. Иначе --- define properties
← →
mikeflat © (2004-04-24 14:34) [7]Ребята, стоит унаследовать TMyObject от TWinControl, а TCustomObject от TControl - все работает отлично, правда автоматически прописываются ище свойства Left,Top, With и Height. Все бы хорошо, но они мешают.
Есть еще какие-нибудь варианты?
← →
mikeflat © (2004-04-24 14:34) [7]Ребята, стоит унаследовать TMyObject от TWinControl, а TCustomObject от TControl - все работает отлично, правда автоматически прописываются ище свойства Left,Top, With и Height. Все бы хорошо, но они мешают.
Есть еще какие-нибудь варианты?
← →
Игорь Шевченко © (2004-04-24 18:28) [8]Например так.
TFOPObject = class(TComponent)
private
FTransAmount: Double;
FFOPName: String;
public
constructor CreateFOP(AOwner: TComponent; const AFOPName: string; ATransAmount: Double);
constructor CreateLike (AOwner: TComponent; Source: TFopObject);
published
property FOPName: string read FFOPName write FFOPName;
property TransAmount: Double read FTransAmount write FTransAmount;
end;
TFOPList = class(TList)
private
function GetItems(I: Integer): TFOPObject;
public
procedure Clear; override;
function HasFop (const AName: String): Boolean;
property Items[I: Integer]: TFOPObject read GetItems; default;
end;
TTransObject = class(TComponent)
private
FFOPList : TFOPList;
procedure ReadFOPS (Reader: TReader);
procedure WriteFOPS (Writer: TWriter);
..................
protected
procedure DefineProperties(Filer : TFiler); override;
..................
public
constructor Create (AOwner: TComponent); override;
destructor Destroy; override;
property FOPList : TFOPList read FFOPList;
............
end;
....
procedure TTransObject.DefineProperties(Filer: TFiler);
function DoWriteFOP: Boolean;
begin
Result := FFOPList.Count > 0;
end;
begin
inherited;
Filer.DefineProperty("FOPS", ReadFOPS, WriteFOPS, DoWriteFOP);
.......
end;
procedure TTransObject.ReadFOPS(Reader: TReader);
begin
FFOPList.Clear;
Reader.ReadListBegin;
while not Reader.EndOfList do
FFOPList.Add(Reader.ReadComponent(nil));
Reader.ReadListEnd;
end;
procedure TTransObject.WriteFOPS(Writer: TWriter);
var
I: Integer;
begin
Writer.WriteListBegin;
for I:=0 to Pred(FFOPList.Count) do
Writer.WriteComponent(FFOPList[I]);
Writer.WriteListEnd;
end;
← →
Игорь Шевченко © (2004-04-24 18:28) [8]Например так.
TFOPObject = class(TComponent)
private
FTransAmount: Double;
FFOPName: String;
public
constructor CreateFOP(AOwner: TComponent; const AFOPName: string; ATransAmount: Double);
constructor CreateLike (AOwner: TComponent; Source: TFopObject);
published
property FOPName: string read FFOPName write FFOPName;
property TransAmount: Double read FTransAmount write FTransAmount;
end;
TFOPList = class(TList)
private
function GetItems(I: Integer): TFOPObject;
public
procedure Clear; override;
function HasFop (const AName: String): Boolean;
property Items[I: Integer]: TFOPObject read GetItems; default;
end;
TTransObject = class(TComponent)
private
FFOPList : TFOPList;
procedure ReadFOPS (Reader: TReader);
procedure WriteFOPS (Writer: TWriter);
..................
protected
procedure DefineProperties(Filer : TFiler); override;
..................
public
constructor Create (AOwner: TComponent); override;
destructor Destroy; override;
property FOPList : TFOPList read FFOPList;
............
end;
....
procedure TTransObject.DefineProperties(Filer: TFiler);
function DoWriteFOP: Boolean;
begin
Result := FFOPList.Count > 0;
end;
begin
inherited;
Filer.DefineProperty("FOPS", ReadFOPS, WriteFOPS, DoWriteFOP);
.......
end;
procedure TTransObject.ReadFOPS(Reader: TReader);
begin
FFOPList.Clear;
Reader.ReadListBegin;
while not Reader.EndOfList do
FFOPList.Add(Reader.ReadComponent(nil));
Reader.ReadListEnd;
end;
procedure TTransObject.WriteFOPS(Writer: TWriter);
var
I: Integer;
begin
Writer.WriteListBegin;
for I:=0 to Pred(FFOPList.Count) do
Writer.WriteComponent(FFOPList[I]);
Writer.WriteListEnd;
end;
← →
Юрий Зотов © (2004-04-24 23:20) [9]> mikeflat © (24.04.04 14:34) [7]
Посмотрите, как это сделано в связке TDataSet-TField или в TMenu-TMenuItem. Вам нужно сделать так же.
> Игорь Шевченко © (24.04.04 18:28) [8]
IMHO, такая схема сохранения может привести к проблемам с визуальным наследованием форм, содержащих TTransObject.
← →
Юрий Зотов © (2004-04-24 23:20) [9]> mikeflat © (24.04.04 14:34) [7]
Посмотрите, как это сделано в связке TDataSet-TField или в TMenu-TMenuItem. Вам нужно сделать так же.
> Игорь Шевченко © (24.04.04 18:28) [8]
IMHO, такая схема сохранения может привести к проблемам с визуальным наследованием форм, содержащих TTransObject.
← →
Игорь Шевченко © (2004-04-25 00:12) [10]Юрий Зотов © (24.04.04 23:20)
Я каюсь, этот компонент не предназначается для форм, это сохранение неких данных в поле базы данных типа BLOB :)
Если можно обрисовать проблему с наследованием, был бы признателен :)
← →
Игорь Шевченко © (2004-04-25 00:12) [10]Юрий Зотов © (24.04.04 23:20)
Я каюсь, этот компонент не предназначается для форм, это сохранение неких данных в поле базы данных типа BLOB :)
Если можно обрисовать проблему с наследованием, был бы признателен :)
← →
Юрий Зотов © (2004-04-25 08:22) [11]> Игорь Шевченко © (25.04.04 00:12) [10]
Запись списка компонентов в DFM идет при единственном условии Count > 0. Но, если форма наследует компонент TTransObject от своего предка и в списке по сравнению с этим предком ничего не менялось, то ведь и в этом случае писать список в DFM тоже незачем. А если что-то менялось - то писать надо только изменения.
Здесь же переписка происходит всегда и полностью - что нарушает наследование ресурсов. Если, например, в форме-предке я изменю какое-то свойство в одном из компонентов TFOPObject, то на потомке это не отразится никак - а ведь должно было бы.
"Правильный" механизм сохранения реализуется перекрытием методов GetParentComponent, SetParentComponent, HasParent, GetChildParent, GetChildren и других. При этом компонент- контейнер становится "родителем" своих внутренних компонентов, а их Owner"ом остается форма. Как раз так, например, и работает связка TDataset-TField (и все нормально сохраняется, и все нормально наследуется).
Но реально, конечно, все зависит от задачи. Если визуальное наследование заведомо исключено, то и незачем городить огород.
← →
Юрий Зотов © (2004-04-25 08:22) [11]> Игорь Шевченко © (25.04.04 00:12) [10]
Запись списка компонентов в DFM идет при единственном условии Count > 0. Но, если форма наследует компонент TTransObject от своего предка и в списке по сравнению с этим предком ничего не менялось, то ведь и в этом случае писать список в DFM тоже незачем. А если что-то менялось - то писать надо только изменения.
Здесь же переписка происходит всегда и полностью - что нарушает наследование ресурсов. Если, например, в форме-предке я изменю какое-то свойство в одном из компонентов TFOPObject, то на потомке это не отразится никак - а ведь должно было бы.
"Правильный" механизм сохранения реализуется перекрытием методов GetParentComponent, SetParentComponent, HasParent, GetChildParent, GetChildren и других. При этом компонент- контейнер становится "родителем" своих внутренних компонентов, а их Owner"ом остается форма. Как раз так, например, и работает связка TDataset-TField (и все нормально сохраняется, и все нормально наследуется).
Но реально, конечно, все зависит от задачи. Если визуальное наследование заведомо исключено, то и незачем городить огород.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.04.11;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.05 c