1

TGrid にいくつかのカスタム列を追加しようとしました。たとえば、TCalendarEdit で構成される列を DB にライブバインドします。
このようなものを実装する方法として、2 つの方法を考え出しました。

  1. CalendarEdit をすべての行に配置します。
    問題は次のとおりです。カスタム TCalendarEdit 列を作成 してグリッドに配置できます が、それをデータセット にライブバインドする と、デフォルトの文字列列ビューにドロップされます!
    TDateColumn = class(TColumn)
    protected
    function CreateCellControl: TStyledControl; override;
    end;
    function TDateColumn.CreateCellControl: TStyledControl;
    begin
    Result := TDateCell.Create(grid);
    Result.Parent := grid;
    end;


    procedure TForm1.FormCreate(Sender: TObject);
    var
    cec: TDateColumn;
    begin
    cec:=TDateColumn.Create(grid1);
    grid1.AddObject(cec);
    end;

    LinkGridToDataSource1.Columns.Items[LinkGridToDataSource1.Columns.Count-1].MemberName:='date';

  2. グリッドセルにコントロールを描画し、それをクリックして破棄し、グリッド上の他の場所をクリックします(データをグリッドに書き込みます)。
    問題は次のとおりです:セルOnClickの座標とサイズを取得するにはどうすればよいですか?

ありがとうございました。

4

3 に答える 3

1

私は最初の部分の解決策しか得られませんでした。元のソースのColumnCreateの実装がおかしいため、少し注意が必要です。

どういう理由ですか?

ユニットFmx.Bind.Grid(Win32のパス%programfiles%\Embarcadero\RAD Studio\10.0\source\databinding\components)とメソッド(500行目から開始)を見てください

function TLinkGridToDataSourceControlManager.CreateColumn( 
  const ADescription : TCreateColumnDescription; AGrid : TCustomGrid ) : TColumn;

列は、に関連して、ADescription.ColumnStyleまたは空の場合に作成されADescription.MemberTypeます。ただし、登録済みのクラスに基づくものではなく、ハードコーディングされています。

TColumnStyleNameは、先頭なしでColumnClassから構築されるため(たとえば、Class TStringColumn=> ColumnStyle ) 、これは奇妙StringColumnです。

なぜEmbaはColumnStyleに基づいて登録済みのクラスを検索しなかったのですか?

FindClass( 'T' + ADescription.ColumnStyle )

もしそうなら、あなたはあなた自身のColumnClassesを登録することができTMyColumn、ColumnStyleプロパティをに設定MyColumnすればすべてがうまくいくでしょう。このColumnClassをパッケージとしてインストールしない限り、PropertyEditorでこのColumnStyleを表示することはできませんでしたが(PropertyEditorもハードコーディングされているため、これは機能しません)、OI内で設定できることを気にします。

柔軟になりましょう

これを修正するには、手作業でいくつかの手順を実行する必要があります

  1. 新しいパスにコピーFmx.Bind.Grid.pasします(プロジェクトが実行したか、有効なDelphi検索/ライブラリパス)
  2. 名前を変更しますFmx.Bind.GridAdv.pas
  3. ここで、このコピーのat行にFmx.Bind.Grid置き換える必要がありますFmx.Bind.GridAdv

    9、10、455行目

  4. 内部の柔軟性を得るには、これを置き換えます(500行目から)

    function TLinkGridToDataSourceControlManager.CreateColumn(
      const ADescription: TCreateColumnDescription; AGrid: TCustomGrid): TColumn;
    begin
      Result := nil;
      if ADescription.ColumnStyle <> '' then
    

    これとともに

    function TLinkGridToDataSourceControlManager.CreateColumn( 
      const ADescription : TCreateColumnDescription; AGrid : TCustomGrid ) : TColumn;
     // ** MOD START **
     type
       TColumnClass = class of TColumn;
     var
       LColumnClass : TColumnClass;
     // ** MOD END **
     begin
       Result := nil;
       if ADescription.ColumnStyle <> '' then
     // ** MOD START **
         begin
           LColumnClass := TColumnClass( FindClass( 'T' + ADescription.ColumnStyle ) );
           if LColumnClass <> nil
           then
             begin
               Result := LColumnClass.Create( FCustomGrid );
             end else 
     // ** MOD END **
    

    下のいくつかの行を閉じる必要がありますbegin

    // ** MOD START **
        end;
    
    // ** MOD END **
    
      if Result = nil then
        case ADescription.MemberType of
    
  5. ファイルを保存します

カスタム列

TNumberColumnサンプルとして、から派生した単純なものを使用しTStringColumnます。カスタム列クラスを登録する必要があることを忘れないでください。

unit FMX.Grid.Columns;

interface

uses
  FMX.Grid, FMX.Types, FMX.Menus;

type
  TNumberColumn = class( TStringColumn )
  protected
    function CreateCellControl : TStyledControl; override;
  end;

implementation

{ TNumberColumn }

function TNumberColumn.CreateCellControl : TStyledControl;
begin
  Result                            := inherited;
  ( Result as TTextCell ).TextAlign := TTextAlign.taTrailing;
end;

initialization

RegisterFmxClasses( [TNumberColumn] );

end.

使い方?

通常どおりフォームを作成し、一部の列のグリッドを使用してバインディングを作成します。

パッチを実行するには、使用順序に注意する必要があります。パッチを適用したユニットは、元のユニットの後にある必要があります。

unit Main_ViewU;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Rtti, System.Classes,
  System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.Grid,
  FMX.Layouts, Data.Bind.GenData, Data.Bind.EngExt, FMX.Bind.DBEngExt,

  FMX.Bind.Grid, // <-- original unit
  FMX.Bind.GridAdv, // <-- patched unit

  FMX.Grid.Columns, // CustomColumns unit

  System.Bindings.Outputs, FMX.Bind.Editors,
  Data.Bind.Components, Data.Bind.Grid, Data.Bind.ObjectScope;

type
  TForm1 = class( TForm )
    Grid1 : TGrid;
    DataGeneratorAdapter1 : TDataGeneratorAdapter;
    AdapterBindSource1 : TAdapterBindSource;
    BindingsList1 : TBindingsList;
    LinkGridToDataSource1 : TLinkGridToDataSource;
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1 : TForm1;

implementation

{$R *.fmx}

end.

最後のステップでは、いくつかの列ColumnStyleをtoに設定しNumberColumn、プログラムを実行して、これらの列が正しく配置されていることを確認します。

Fmx.Bind.GridAdv.pasを除く完全なサンプルプロジェクトソース

于 2013-01-08T17:19:42.450 に答える
0

セルまたは列のコードはわかりませんが、以下のようなものが表示されると思います。

セル内のMouseDownで好きなことを行うことができます。列で処理する場合は、イベントを作成してCreateCellControlで設定します。

type TDateCell = class(TCalendarEdit)
  protected
    procedure MouseDown(Button: TMouseButton;Shift: TShiftState;X, Y: Single);override;
  end;

type TDateColumn = class(TColumn)
  protected
    function CreateCellControl: TStyleControl;override;
  end;

procedure TDateCell.MouseDown(Button: TMouseButton;Shift: TShiftState;X, Y: Single)
begin
  inherited;
  //Custom stuff here with X,Y
end;

function TDateColumn.CreateCellControl: TStyledControl;
begin
  Result := TDateCell.Create;
  Result.Parent := Self;
end;
于 2012-09-28T14:49:44.983 に答える
0

ライブバインディングはグリッド列とセルの作成を制御するため、列と bindmanager およびその他のライブバインディング コンポーネントをサブクラス化することは、おそらく実用的でもエレガントでもありません。あなたが持っているもので作業してください。

グリッドの OnPainting イベントでセルにアクセスできます

Somecell := TTextCell(Grid1.Columns[Col].Children[Row]);

TextCell を Visible := False に設定し、TCalendarEdit (所有者はフォーム、親は列) を同じ位置に作成することをお勧めします。TextCell.Text を使用して、日付を CalendarEdit に書き込みます。

于 2013-10-28T08:41:22.013 に答える