2012-07-18 3 views
2

여러 Delphi 2005 응용 프로그램을 XE2로 변환하고 더 이상 사용할 수없는 구성 요소를 사용하므로 기본 구성을 처리하기 위해 자체 구성 요소를 작성했습니다. 구성 요소를 폼에 놓을 때 일반적으로 괜찮습니다. 그러나 DFM에 속성이 이미 설정된이 구성 요소가 포함 된 VCL 폼을 열면 문제가 발생합니다.사용자 정의 Delphi 구성 요소에 Columns.Columns 속성 구현

델파이 2005 DFM은 다음과 같이 포함되어 있습니다

내 구성 요소가 된 TCollection에서 상속하는 클래스를 기반으로 열 속성을 가지고 있으며, 나는 상속 사용하는 컬렉션에 열 속성을 추가 한 경우에도
object ExtendedGrid1: TExtendedGrid 
    Left = 32 
    Top = 16 
    Width = 577 
    Height = 257 
    TabOrder = 0 
    Columns.Columns = (
     'OE6.02' 
     (
     'Test1' 
     64 
     False 
     0 
     'clWindowText' 
     -11 
     'Tahoma' 
     0 
     8 
     False 
     False 
     False 
     False 
     0 
     1 
     0 
     0 
     0 
     1 
     0 
     'clWindowText' 
     -11 
     'Tahoma' 
     0 
     8 
     False 
     False 
     False 
     False 
     0 
     1 
     0 
     'test2' 
     64 
     False 
     0 
     'clWindowText' 
     -11 
     'Trebuchet MS' 
     0 
     8 
     True 
     True 
     False 
     False 
     0 
     1 
     0 
     0 
     0 
     1 
     0 
     'clWindowText' 
     -11 
     'Tahoma' 
     0 
     8 
     False 
     False 
     False 
     False 
     0 
     1 
     0 
     '' 
     '0')) 
    RowHeights = (
     19 
     19) 
    end 

항목, 디자이너에서 양식을 열려고 시도 할 때이 오류가 발생합니다.

양식을 만드는 동안 오류가 발생했습니다. MyGrid1.Columns.Columns : 속성 열을 읽는 중 오류가 없습니다.

Columns = < 
    item 
    Title = 'Test1' 
    Width = 64 
    Editable = False 
    HeaderClipStyle = csClip 
    HeaderFont.Charset = DEFAULT_CHARSET 
    HeaderFont.Color = clWindowText 
    HeaderFont.Height = -11 
    HeaderFont.Name = 'Tahoma' 
    HeaderFont.Style = [] 
    HeaderHAlign = haRight 
    HeaderInnerBevel = bvNone 
    HeaderOuterBevel = bvNone 
    HeaderBorderWidth = 0 
    HeaderBevelWidth = 0 
    ContentsClipStyle = csClip 
    ContentsFont.Charset = DEFAULT_CHARSET 
    ContentsFont.Color = clWindowText 
    ContentsFont.Height = -11 
    ContentsFont.Name = 'Tahoma' 
    ContentsFont.Style = [] 
    ComboFilled = False 
    ComboEditable = False 
    end 
    item 
    Title = 'test2' 
    Width = 64 
    Editable = False 
    HeaderClipStyle = csClip 
    HeaderFont.Charset = DEFAULT_CHARSET 
    HeaderFont.Color = clWindowText 
    HeaderFont.Height = -11 
    HeaderFont.Name = 'Trebuchet MS' 
    HeaderFont.Style = [] 
    HeaderInnerBevel = bvNone 
    HeaderOuterBevel = bvNone 
    HeaderBorderWidth = 0 
    HeaderBevelWidth = 0 
    ContentsClipStyle = csClip 
    ContentsFont.Charset = DEFAULT_CHARSET 
    ContentsFont.Color = clWindowText 
    ContentsFont.Height = -11 
    ContentsFont.Name = 'Tahoma' 
    ContentsFont.Style = [] 
    ComboFilled = False 
    ComboEditable = False 
    end 
    end> 

누군가가 나를 수있는 몇 가지 기사 또는 설명을 날 포인트 : 내 구성 요소의 새 복사본을 만드는 경우

후 나는 DFM에서 완전히 다른 무언가를보고, 위로 열을 설정 내 맞춤 구성 요소를 작성하여 이전 Delphi 2005 DFM을 처리 할 수 ​​있습니까? 감사.

+1

난 당신이 WriteListBegin/WriteListEnd 및 ReadListBegin/ReadListEnd을 사용할 필요가하려고하는 것을 생각한다. TCustomGrid에서 RowHeights 및 ColWidths 속성을 처리하는 방법을 살펴보십시오. TCustomGrid.DefineProperties를 살펴보십시오. –

답변

3

이것은 완전한 답변은 아니지만 당신이 (당신이 TColumn에 필요한 모든 속성을 추가하고 ReadColumn/WriteColumn 방법에서의 읽기/쓰기를 구현해야) 시작 수 있습니다

unit Unit2; 

interface 

uses 
    Classes, SysUtils, Contnrs; 

type 
    TColumn = class 
    private 
    FName: string; 
    FWidth: Integer; 
    public 
    property Name: string read FName; 
    property Width: Integer read FWidth; 
    end; 

    TColumns = class(TPersistent) 
    private 
    FItems: TObjectList; 
    FOwner: TComponent; 
    function GetCount: Integer; 
    function GetItems(Index: Integer): TColumn; 
    protected 
    procedure DefineProperties(Filer: TFiler); override; 
    function GetOwner: TPersistent; override; 
    function ReadColumn(Reader: TReader): TColumn; 
    procedure ReadColumns(Reader: TReader); 
    procedure WriteColumn(Writer: TWriter; Column: TColumn); 
    procedure WriteColumns(Writer: TWriter); 
    public 
    constructor Create(AOwner: TComponent); 
    destructor Destroy; override; 
    procedure Assign(Source: TPersistent); override; 
    property Count: Integer read GetCount; 
    property Items[Index: Integer]: TColumn read GetItems; default; 
    end; 

    TTestComponent = class(TComponent) 
    private 
    FColumns: TColumns; 
    procedure AddTestColumns; 
    procedure SetColumns(Value: TColumns); 
    public 
    constructor Create(AOwner: TComponent); override; 
    destructor Destroy; override; 
    published 
    property Columns: TColumns read FColumns write SetColumns; 
    end; 

procedure Register; 

implementation 

procedure Register; 
begin 
    RegisterComponents('Test', [TTestComponent]); 
end; 

{ TColumns } 

function TColumns.GetCount: Integer; 
begin 
    Result := FItems.Count; 
end; 

function TColumns.GetItems(Index: Integer): TColumn; 
begin 
    Result := TColumn(FItems[Index]); 
end; 

function TColumns.GetOwner: TPersistent; 
begin 
    Result := FOwner; 
end; 

procedure TColumns.DefineProperties(Filer: TFiler); 
begin 
    inherited DefineProperties(Filer); 
    Filer.DefineProperty('Columns', ReadColumns, WriteColumns, Count > 0); 
end; 

function TColumns.ReadColumn(Reader: TReader): TColumn; 
begin 
    Result := TColumn.Create; 
    try 
    Result.FName := Reader.ReadString; 
    Result.FWidth := Reader.ReadInteger; 
    except 
    Result.Free; 
    raise; 
    end; 
end; 

procedure TColumns.ReadColumns(Reader: TReader); 
var 
    Version: string; 
begin 
    Reader.ReadListBegin; 
    Version := Reader.ReadString; 
    if Version = 'OE6.02' then 
    begin 
    Reader.ReadListBegin; 
    FItems.Clear; 
    while not Reader.EndOfList do 
     FItems.Add(ReadColumn(Reader)); 
    Reader.ReadListEnd; 
    end; 
    Reader.ReadListEnd; 
end; 

procedure TColumns.WriteColumn(Writer: TWriter; Column: TColumn); 
begin 
    Writer.WriteString(Column.FName); 
    Writer.WriteInteger(Column.FWidth); 
end; 

procedure TColumns.WriteColumns(Writer: TWriter); 
var 
    I: Integer; 
begin 
    Writer.WriteListBegin; 
    Writer.WriteString('OE6.02'); 
    Writer.WriteListBegin; 
    for I := 0 to Count - 1 do 
    WriteColumn(Writer, Items[I]); 
    Writer.WriteListEnd; 
    Writer.WriteListEnd; 
end; 

constructor TColumns.Create(AOwner: TComponent); 
begin 
    inherited Create; 
    FOwner := AOwner; 
    FItems := TObjectList.Create; 
end; 

destructor TColumns.Destroy; 
begin 
    FItems.Free; 
    inherited Destroy; 
end; 

procedure TColumns.Assign(Source: TPersistent); 
var 
    Column: TColumn; 
    I: Integer; 
begin 
    if Source is TColumns then 
    begin 
    FItems.Clear; 
    for I := 0 to TColumns(Source).Count - 1 do 
    begin 
     Column := TColumn.Create; 
     try 
     Column.FName := TColumns(Source)[I].FName; 
     Column.FWidth := TColumns(Source)[I].FWidth; 
     FItems.Add(Column); 
     except 
     Column.Free; 
     raise; 
     end; 
    end; 
    end; 
end; 

{ TTestComponent } 

procedure TTestComponent.AddTestColumns; 
    procedure AddColumn(const AName: string; AWidth: Integer); 
    var 
    Column: TColumn; 
    begin 
    Column := TColumn.Create; 
    try 
     Column.FName := AName; 
     Column.FWidth := AWidth; 
     FColumns.FItems.Add(Column); 
    except 
     Column.Free; 
     raise; 
    end; 
    end; 
begin 
    AddColumn('Test1', 64); 
    AddColumn('Test2', 128); 
end; 

procedure TTestComponent.SetColumns(Value: TColumns); 
begin 
    FColumns.Assign(Value); 
end; 

constructor TTestComponent.Create(AOwner: TComponent); 
begin 
    inherited Create(AOwner); 
    FColumns := TColumns.Create(Self); 
    AddTestColumns; 
end; 

destructor TTestComponent.Destroy; 
begin 
    FColumns.Free; 
    inherited Destroy; 
end; 

end. 

이 코드는 생산 .DFM에서 다음과 같은 결과 :

object Form1: TForm1 
    Left = 0 
    Top = 0 
    Caption = 'Form1' 
    ClientHeight = 282 
    ClientWidth = 418 
    Color = clBtnFace 
    Font.Charset = DEFAULT_CHARSET 
    Font.Color = clWindowText 
    Font.Height = -11 
    Font.Name = 'Tahoma' 
    Font.Style = [] 
    OldCreateOrder = False 
    PixelsPerInch = 96 
    TextHeight = 13 
    object TestComponent1: TTestComponent 
    Columns.Columns = (
     'OE6.02' 
     (
     'Test1' 
     64 
     'Test2' 
     128)) 
    Left = 200 
    Top = 144 
    end 
end 
+0

이전 Delphi 2005 양식에서 열 속성 정보를 읽을 수 있다는 점에서 훌륭하게 작동했습니다. 그러나 원래 구성 요소의 컬렉션 속성 편집기를 자동으로 포함하는 TCollection 및 TCollectionItem을 사용했지만 새 구현에서는 디자이너를 통해 개별 열 개체 속성을 변경할 수 없었습니다. Object Inspector에서 모눈을 볼 때 Columns 속성에 더 이상 ... 버튼이 없습니다. 내 자신의 속성 편집기를 작성해야합니까? – SiBrit

관련 문제