Форум: "Компоненты";
Текущий архив: 2005.11.06;
Скачать: [xml.tar.bz2];
ВнизНе сохраняется свойство компонента Найти похожие ветки
← →
Tormoz (2004-07-08 14:55) [0]Уважаемые Мастера, посоветуйте!!!
Проблема в следующем:
Создаю компонент, у которого есть свойство-класс, содержащее подсвойство-компонент:...
Type
TGridHeader = class(TPersistent)
private
fHeaders :TTreeView;
fRemarks:String;
procedure SetHeaders(value:TTreeView);
procedure SetRemarks(value:string);
protected
public
constructor create;
destructor destroy;override;
published
property Headers:TTreeView read fHeaders write SetHeaders;
property remarks:string read fremarks write SetRemarks;
end;
...
// Собственно редактор свойств :
TGridHeaderProperty = class(TClassProperty)
public
procedure Edit; override;
function GetAttributes:TPropertyAttributes;override;
end;
procedure TGridHeaderProperty.Edit;
Var
fmHDRDlg:TfmHDRDlg; // форма редактора свойств
begin
Try
fmHDRDlg:=TfmHDRDlg.Create(nil);
if fmHDRDlg.Execute(TComponent(GetComponent(0)), // МОЖЕТ ЗДЕСЬ ЧЕ НЕ ТАК ???
TGridHeader(GetOrdValue))
then SetOrdValue(Longint(TGridHeader(GetOrdValue)));
Finally
fmHDRDlg.Free;
End;
end;
...
// КОМПОНЕНТ :
TeG = class(TDBGrid)
private
fGridHeader:TGridHeader;
procedure SetGridHeader(Value:TTreeView);
protected
public
constructor Create (AOwner : TComponent); override;
destructor Destroy;override;
published
property GridHeader:TGridHeader read fGridHeader
write fGridHeader;
end;
...
constructor TeG.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
fGridHeader := TGridHeader.Create;
end;
destructor TeG.Destroy;
begin
if fGridHeader<>nil
then
begin
fGridHeader.Headers.Items.Clear;
fGridHeader.Free;
end;
inherited destroy;
end;
...
И регистрирую редактор свойств:
procedure Register;
begin
RegisterPropertyEditor(TypeInfo(TGridHeader),nil,"",
HDREdit.TGridHeaderProperty);
RegisterComponents("Standard", [TeG]);
end;
...
Редактор свойств - форма, на которой есть twHeader:TTreeView.
В twHeader закачиваю fGridHeader.
В design-time любые изменения сделанные в редакторе свойств сохраняются.
Если же я закрывал форму со своим компонентом, то при след.загрузке формы у моего компонента свойство GridHeader теряет все изменения пред. сеанса работы с формой. Это при том, что свойство Remarks хранит изменения!!!
Чего не так делаю ???
← →
Юрий Зотов © (2004-07-08 15:37) [1]Приведите ПОЛНУЮ реализацию обоих классов. Редактор свойства можно не приводить - к сохранению и чтению свойств он никакого отношения не имеет.
← →
Tormoz (2004-07-08 15:56) [2]To Юрий Зотов © (08.07.04 15:37) [1]
// Компонент
unit eG;
interface
uses
Windows, Messages, Classes, Graphics, Controls, Grids, DBGrids, Dialogs,
SysUtils, HDREdit, DsgnIntf, Comctrls;
type
TeG = class(TDBGrid)
private
fGridHeader:TGridHeader;
protected
public
constructor Create (AOwner : TComponent); override;
destructor Destroy;override;
published
property GridHeader:TGridHeader read fGridHeader
write fGridHeader;
end;
procedure Register;
implementation
//-----------------------------------------------------------------------------
constructor TeG.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
fGridHeader := TGridHeader.Create;
end;
//-----------------------------------------------------------------------------
destructor TeG.Destroy;
begin
if fGridHeader<>nil
then
begin
fGridHeader.Headers.Items.Clear;
fGridHeader.Free;
end;
inherited destroy;
end;
//-----------------------------------------------------------------------------
procedure Register;
begin
RegisterPropertyEditor(TypeInfo(TGridHeader),nil,"",
HDREdit.TGridHeaderProperty);
RegisterComponents("Standard", [TeG]);
end;
end.
// ============================================================
unit HDREdit;
interface
Uses
DsgnIntf,Windows, Messages, SysUtils,
Classes,ComCtrls, Dialogs,Forms, DBGrids, TypInfo;
Type
// Класс "Сложные заголовки" для TDBGrid
TGridHeader = class(TPersistent)
private
fHeaders :TTreeView;
fRemarks:String;
procedure SetHeaders(value:TTreeView);
procedure SetRemarks(value:string);
protected
public
procedure RestoreDefaults(AOwner:TDBGrid);
constructor create;
destructor destroy;override;
published
property Headers:TTreeView read fHeaders write SetHeaders;
property Remarks:string read fRemarks write SetRemarks;
end;
TGridHeaderProperty = class(TClassProperty)
public
procedure Edit; override;
function GetAttributes:TPropertyAttributes;override;
end;
implementation
Uses
HDRDlg, eG;
//-----------------------------------------------------------------------------
procedure TGridHeader.RestoreDefaults(AOwner:TDBGrid);
Var
i:integer;
begin
// "Ãðóçèì" TColumns
for i:=0 to AOwner.Columns.Count-1 Do
begin
fHeaders.Items.AddObject(nil,
AOwner.Columns[i].Title.Caption,
TObject(nil));
end;
end;
//-----------------------------------------------------------------------------
constructor TGridHeader.Create;
begin
inherited Create;
fHeaders:=TTreeView.Create(nil);
fHeaders.ParentWindow:=Application.Handle;
fRemarks := "Initial remark...";
end;
//-----------------------------------------------------------------------------
destructor TGridHeader.destroy;
begin
if fHeaders<>nil
then
begin
fHeaders.Free;
end;
inherited destroy;
end;
//-----------------------------------------------------------------------------
procedure TGridHeader.SetHeaders(value:TTreeView);
begin
fHeaders.Items.Clear;
fHeaders.Items.Assign(Value.Items);
end;
//-----------------------------------------------------------------------------
procedure TGridHeader.SetRemarks(value:string);
begin
fRemarks:=Value;
end;
//-----------------------------------------------------------------------------
procedure TGridHeaderProperty.Edit;
Var
fmHDRDlg:TfmHDRDlg; // ôîðìà ðåäàêòîðà ñâîéñòâ
begin
Try
fmHDRDlg:=TfmHDRDlg.Create(nil);
if fmHDRDlg.Execute(TComponent(GetComponent(0)),
TGridHeader(GetOrdValue))
then SetOrdValue(Longint(TGridHeader(GetOrdValue)));
Finally
fmHDRDlg.Free;
End;
end;
//-----------------------------------------------------------------------------
function TGridHeaderProperty.GetAttributes:TPropertyAttributes;
begin
result:=[paReadOnly,paDialog];
end;
end.
← →
Юрий Зотов © (2004-07-08 16:41) [3]Компонентские свойства по умолчанию считаются ссылками на внешние компоненты и сохраняются в DFM в виде ссылок - потому Headers и не сохраняется.
Чтобы сохранять внутренний компонент полностью, нужно перекрыть DefineProperties и добавить Read/Write.
Редактор свойства к этому никакого отношения не имееет - он только меняет значение свойства в designtime и за его сохранение/чтение не отвечает.
type
TGridHeader = class(TPersistent)
private
...
procedure ReadHeaders(Reader: TReader);
procedure WriteHeaders(Writer: TWriter);
protected
procedure DefineProperties(Filer: TFiler); override;
...
published
property Headers: TTreeView
read fHeaders write SetHeaders stored False;
...
end;
procedure TGridHeader.DefineProperties(Filer: TFiler);
begin
Filer.DefineProperty("Headers", ReadHeaders, WriteHeaders,
Filer.Ancestor = nil)
end;
procedure TGridHeader.ReadHeaders(Reader: TReader);
begin
FHeaders := Reader.ReadComponent(nil)
end;
procedure TGridHeader.WriteHeaders(Writer: TWriter);
begin
Writer.WriteComponent(FHeaders)
end;
← →
Tormoz (2004-07-08 17:08) [4]To Юрий Зотов © (08.07.04 16:41) [3]
Слушай, спасибо за совет. Такой код я видел в хелпе.Но, признаюсь, ничего не понял. Вот возьмем, к примеру, TGridHeader.WriteHeaders. Он, если я правильно понимаю, запишет FHeaders в компонент TeG.Так ?
Если так, ГДЕ ЕГО ВЫЗЫВАТЬ ?
← →
Юрий Зотов © (2004-07-08 17:50) [5]Он запишет ВЕСЬ компонент FHeaders в DFM, внутри компонента TeG (а еще точнее - внутри объекта TGridHeader).
Вызывать его не надо, Delphi вызовет его сама, когда будет записывать DFM.
← →
Tormoz (2004-07-08 17:58) [6]To Юрий Зотов © (08.07.04 17:50) [5]
Хорошо, понял. Но теперь другие Грабли!!!
На этапе компилияции ошибка:
Incompatible types: "TTreeView" and "TComponent"
Че опять не так ?
← →
Tormoz (2004-07-08 18:06) [7]P.S.
Курсор ставит в конец строки:
FHeaders := Reader.ReadComponent(nil);
← →
Юрий Зотов © (2004-07-08 18:08) [8]Надо просто привести тип компонента к нужному:
FHeaders := TTreeView(Reader.ReadComponent(nil));
← →
Tormoz (2004-07-08 18:15) [9]To Юрий Зотов © (08.07.04 18:08) [8]
Честно признаюсь, сделал это сразу. Все работает в design-time,
но как только я переоткрываю форму (читаю с диска), получаю окошко с нехорошим сообщением:
Error creating form:"=" expected on line 29
и форма не создается !!!
Нет в жизни счастья :(
← →
Юрий Зотов © (2004-07-08 18:54) [10]Приведите первые 35 строк из файла DFM формы в текстовом виде
(только обязательно используйте тегии
)
← →
Юрий Зотов © (2004-07-08 18:56) [11]Вдогонку: stored False надеюсь, указать не забыли?
← →
Tormoz (2004-07-09 17:32) [12]To Юрий Зотов © (08.07.04 18:56) [11]
object Form1: TForm1
Left = 175
Top = 133
Width = 696
Height = 480
Caption = "Form1"
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = "MS Sans Serif"
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object eG1: TeG
Left = 84
Top = 80
Width = 320
Height = 120
TabOrder = 0
TitleFont.Charset = DEFAULT_CHARSET
TitleFont.Color = clWindowText
TitleFont.Height = -11
TitleFont.Name = "MS Sans Serif"
TitleFont.Style = []
GridHeader.remarks = "Any remarks you like..."
GridHeader.Headers = True
TreeView
После TreeView безобразие нарисовано: два квадратика,
потом Left три квадратика GridHeader.Top квадратики и т.д. и .т.п
УЖАС !!!
← →
Tormoz (2004-07-13 15:02) [13]Юра Зотов, есть какие-нибудь мысли по этому вопросу ???
← →
reonid © (2004-07-19 13:05) [14]Помнится, встречался я с чем-то подобным.
Там была проблема в парсере DFM.
попробуй, например, сохранить компонент
не через DefineProperty, а через DefineBinaryProperty.
← →
Мимо проходил (2004-07-30 08:41) [15]Удалено модератором
← →
don-do (2004-07-30 14:59) [16]Обрати внимание на процедуру
DefineProperties в самом TDBGrid
и как он загружает колонки
← →
Peperovich (2005-02-17 11:57) [17]help me
У меня аналогичная проблема только выводится сообщение
error creting form : identifier expected on line 430
Страницы: 1 вся ветка
Форум: "Компоненты";
Текущий архив: 2005.11.06;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.042 c