Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Компоненты";
Текущий архив: 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
 // "&#195;&#240;&#243;&#231;&#232;&#236;" 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; // &#244;&#238;&#240;&#236;&#224; &#240;&#229;&#228;&#224;&#234;&#242;&#238;&#240;&#224; &#241;&#226;&#238;&#233;&#241;&#242;&#226;
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
2-1129119784
Del_programmer
2005-10-12 16:23
2005.11.06
Динамика


3-1127454524
Aliv
2005-09-23 09:48
2005.11.06
invalid filename при попытке создать таблицу


4-1125553929
Ola
2005-09-01 09:52
2005.11.06
Как писать и читать из реестра?


9-1119515222
Slavikk
2005-06-23 12:27
2005.11.06
(GLScene) Кто какие скрипты использует?


3-1127449796
SQL-nik
2005-09-23 08:29
2005.11.06
Обнуление "счетчика" уникального поля





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский