Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - Abgeleitete cxGrid-Komponente und alte dxGrid Dfm


Quitzlinga - Mi 19.06.19 10:01
Titel: Abgeleitete cxGrid-Komponente und alte dxGrid Dfm
Hallo zusammen,

ich versuche zur Zeit eine alte Grid-Komponente ( TdxGrid, Vorgänger vom jetzigen Quantum-Grid ) auf Delphi Tokio zu ersetzen. Dazu habe ich eine eigene Komponente geschrieben, welche als Erstz dient und auch so weit schon funktioniert. Nun sollen aber noch die alten Spalten übernommen werden und da habe ich zur Zeit Probleme und zwar werden die Spalten nicht als Subkomponente dem neuem Grid zugeordnet sondern dem Formular aber dazu gleich mehr.

Die Komponente sieht zur Zeit so aus:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
type
  TdxDBGridColumn = class( TComponent )
    private
      fCaption : string;
      fVisible : boolean;
      fWidth   : integer;
      fBandIndex : integer;
      fRowIndex  : integer;
      fFieldName : string;
    public
      constructor Create( aOwner : TComponent ); override;
    published
      property Caption : string read fCaption write fCaption;
      property Visible : boolean read fVisible write fVisible;
      property Width   : integer read fWidth write fWidth;
      property BandIndex : integer read fBandIndex write fBandIndex;
      property RowIndex  : integer read fRowIndex write fRowIndex;
      property FieldName : string read fFieldname write fFieldname;
  end;

  TdxDBGridColumnList = class( TObjectlist<TdxDBGridColumn> )
    private
    public
  end;

  TdxDBGridMaskColumn = class( TdxDBGridColumn )
    private
    public
  end;

  TdxDBGridDateColumn = class( TdxDBGridColumn )
    private
    public
  end;

  TdxDBGrid = class( TcxGrid )
    private
      // hier sollen einmal die alten Felder rein
      fOldFields : TdxDBGridColumnList;
    protected
      procedure DefineProperties( Filer: TFiler ); override;
      procedure Loaded; override;
    public
      constructor Create( aOwner : TComponent ); override;
      destructor Destroy(); override;
    published
  end;

  procedure Register;

implementation

uses SysUtils;

//------------------------------ TdxGrid ---------------------------------------
constructor TdxDBGrid.Create( aOwner : TComponent );
begin
  inherited Create( aOwner );
  fOldFields := TdxDBGridColumnList.Create( true );
end;

destructor TdxDBGrid.Destroy();
begin
  FreeAndNil( fOldFields );
end;

procedure TdxDBGrid.DefineProperties( Filer: TFiler );
begin
  inherited;
end;

procedure TdxDBGrid.Loaded;
begin
  try
    inherited Loaded;
  except
    ApplicationHandleException(Self);
  end;
end;
//----------------------------------- TdxDBGridColumn --------------------------
constructor TdxDBGridColumn.Create( aOwner : TComponent );
begin
  inherited Create( aOwner );
  SetSubComponent( true );
end;
//----------------------------------- Register ---------------------------------
procedure Register;
begin
  RegisterComponents( 'wawi', [TdxDBGrid, TdxDBGridColumn, TdxDBGridMaskColumn,
                               TdxDBGridDateColumn]);
end;


Und eine typische alte dfm ( Grid-Teil extrahiert ):


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
inherited DBG_Analyze: TdxDBGrid
      Width = 917
      Height = 458
      SummaryGroups = <
        item
          DefaultGroup = False
          SummaryItems = <
            item
            end>
        end>
      object DBG_AnalyzeUniqueField: TdxDBGridColumn
        Visible = False
        Width = 37
        BandIndex = 0
        RowIndex = 0
        FieldName = 'UniqueField'
      end
      object DBG_Analyzeuserid_ref: TdxDBGridMaskColumn
        Width = 123
        BandIndex = 0
        RowIndex = 0
        FieldName = 'userid_ref'
      end
      object DBG_Analyzepnav_punkt: TdxDBGridMaskColumn
        Caption = 'PNAV'
        Width = 74
        BandIndex = 0
        RowIndex = 0
        FieldName = 'pnav_punkt'
      end
      object DBG_Analyzepnav_text: TdxDBGridMaskColumn
        Caption = 'PNAV Text'
        Width = 552
        BandIndex = 0
        RowIndex = 0
        FieldName = 'pnav_text'
      end
      object DBG_Analyzezugriff: TdxDBGridMaskColumn
        Caption = 'Zugriff'
        Width = 61
        BandIndex = 0
        RowIndex = 0
        FieldName = 'zugriff'
      end
    end


Rufe ich jetzt das Formular mit meiner Ersatzkomponente auf und schaue in die DFM, so lässt sich sehen, das die Spalten als Komponenten dem übergeordnetem Formular zugeordnet sind aber nicht dem Grid, was ich sonst vermutet hätte.

Ziel ist es, das ich die alten Spalten entweder in der Liste fOldFields ablege und diese dann in der neuen DFM überhaupt nicht mehr auftauchen oder dies als Spalten im neuen Grid in der DFM auftauchen und damit auch gesichert werden ( Dynamische Anlage von Spalten im Quantum-Grid ist bekannt).

Meine bisherigen Versuche zum Vorgehen waren folgende:

1. TADOTable Quelltext durchsucht, wie diese Spalten gesichert werden. Dabei bin ich auf DefineProperties und Loaded nach Googeln und Suche in diversen Foren gestossen. Ergab aber nur als Ergebnis, das
DefineProperties für Named-Properties der Komponente genützt werden ( ist ja hier leider nicht der Fall ).
2. Die Spalten sind Subkomponenten also müssen sie auch bei der Erstellung so gekennzeichnet sein. Also mit SetSubComponent(true) gekennzeichnet aber dasselbe Ergebnis.
3. Ich habe jetzt noch die Vermutung, das die Registrierung der neuen Spalten falsch ist, denn kein Grid, was ich kenne, macht das aber da kann ich mich auch irren.

Vielleicht könnt Ihr mir etwas Hilfe in der Angelegenheit geben, denn mittlerweile gehen mir die Ideen und die Suchparameter aus.

MfG

Quitzlinga


Quitzlinga - Fr 28.06.19 17:07

So, ich bin nun schon einen kräftigen Schritt weiter gekommen : Das zauberwort heist Collection und CollectionItem.

Im Objektinspektor wird jetzt der neue Punkt OldFields angezeigt und ist auch editierbar. Mein Hauptproblem, die alten Spalten aus der DFM zu übernehmen scheitert jedoch nach wie vor.
Fehlermeldung : Fehler beim Lesen des Formulars : Klasse TdxDBGridColumn nicht gefunden, der Verweis auf die Unit OldDxGrid steht aber in der ersten Uses-Klausel des Formulars.
Wo steckt jetzt mein Denkfehler ?


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
type
  TdxDbgridOption = (egoColumnSizing, egoColumnMoving, egoEditing, egoTabs,
                     egoTabThrough, egoRowSelect, egoMultiSelect, egoCanDelete,
                     egoConfirmDelete, egoCanNavigation, egoCanAppend,
                     egoCancelOnExit, egoImmediateEditor, egoCanInsert,
                     egoLoadAllRecords, egoPreview, egoDrawEndEllipsis,
                     egoStoreToRegistry, egoAutoWidth, egoShowHourGlass,
                     egoCaseInsensitive, egoDblClick, egoIndicator,
                     egoExtMultiSelect, egoResetColumnFocus, egoExtCustomizing,
                     egoHideFocusRect, egoStoreToIniFile, egoUseLocate,
                     egoSmartReload, egoSmartRefresh, egoSeekDetail
                     );

  TdxDbgridOptions = Set of TdxDbgridOption;

  TdxDBGridColumn = class( TCollectionItem )
    private
      fCaption : string;
      fVisible : boolean;
      fWidth   : integer;
      fBandIndex : integer;
      fRowIndex  : integer;
      fFieldName : string;
    public
      constructor Create( Collection: TCollection ); override;
    published
      property Caption : string read fCaption write fCaption;
      property Visible : boolean read fVisible write fVisible;
      property Width   : integer read fWidth write fWidth;
      property BandIndex : integer read fBandIndex write fBandIndex;
      property RowIndex  : integer read fRowIndex write fRowIndex;
      property FieldName : string read fFieldname write fFieldname;
  end;

  TdxDBGridMaskColumn = class( TdxDBGridColumn )
    private
    public
  end;

  TdxDBGridDateColumn = class( TdxDBGridColumn )
    private
    public
  end;

  TdxDBGridCheckColumn = class( TdxDBGridColumn )
    private
      fValueChecked : string;
      fValueUnchecked : string;
    public
    published
      property ValueChecked : string read fValueChecked write fValueChecked;
      property ValueUnchecked : string read fValueUnChecked write fValueUnChecked;
  end;

  TdxDBGridItemList = class(TCollection)
  private
    fItems: array of TdxDBGridColumn;
    fOwner: TComponent;
  protected
    function GetItem( aIndex: Integer ) : TdxDBGridColumn;
    procedure SetItem( aIndex: Integer; aItem: TdxDBGridColumn );
  public
    constructor Create( aOwner : TComponent );
    function Add(): TdxDBGridColumn; overload;
    function GetOwner: TPersistent; override;
    property Items[Index: Integer]: TdxDBGridColumn read GetItem write SetItem; default;
  end;

  TdxDBGrid = class( TcxGrid )
    private
      fOldkeyField : string;
      fOldOptions : TdxDbgridOptions;
      fOldFields : TdxDBGridItemList;
      procedure TransferOldOptions();
      procedure setOldFields(const aValue: TdxDBGridItemList);
    protected
      procedure DefineProperties( Filer: TFiler ); override;
      procedure Loaded; override;
    public
      constructor Create( aOwner : TComponent ); override;
      destructor Destroy(); override;
    published
      property KeyField : string read fOldkeyField write fOldKeyField;
      property Options : TdxDbgridOptions read fOldOptions write fOldOptions;
      property OldFields : TdxDBGridItemList read fOldFields write setOldFields;
  end;

  procedure Register;

implementation

uses SysUtils;

//------------------------------ TdxDBGridItemList -----------------------------
constructor TdxDBGridItemList.Create( aOwner : TComponent );
begin
  inherited Create( TdxDBGridColumn );
  fOwner := aOwner;
end;

function TdxDBGridItemList.GetOwner: TPersistent;
begin
  Result := fOwner;
end;

function TdxDBGridItemList.Add(): TdxDBGridColumn;
begin
  Result := inherited Add as TdxDBGridColumn;
end;

function TdxDBGridItemList.GetItem(aIndex: Integer): TdxDBGridColumn;
var
  i: integer;
begin
  result := TdxDBGridColumn( inherited Items[ aIndex ] );
end;

procedure TdxDBGridItemList.SetItem( aIndex: Integer; aItem: TdxDBGridColumn);
begin
  Items[ aIndex ].Assign( aItem );
end;
//------------------------------ TdxGrid ---------------------------------------
constructor TdxDBGrid.Create( aOwner : TComponent );
begin
  inherited Create( aOwner );
  fOldFields := TdxDBGridItemList.Create( Self );
end;

destructor TdxDBGrid.Destroy();
begin
  FreeAndNil( fOldFields );
  inherited;
end;

procedure TdxDBGrid.DefineProperties( Filer: TFiler );
begin
  inherited;
end;

procedure TdxDBGrid.setOldFields(const aValue: TdxDBGridItemList);
begin
  fOldFields.Assign( aValue );
end;

// Wird nach Create und dem Laden der Properties aus der Form aufgerufen
procedure TdxDBGrid.Loaded;
begin
  try
    inherited Loaded;
    TransferOldOptions();
  except
    ApplicationHandleException(Self);
  end;
end;