2012-02-12 39 views
6

Tôi đang sử dụng điều khiển Lưới điều khiển FireMonkey nhưng có vấn đề đang xảy ra khi cố gắng căn chỉnh cột thẳng hàng. Từ các bài đăng của người dùng khác, tôi đã quản lý để tạo một loại TColumn mới, áp dụng một kiểu cho văn bản này (văn bản là HorzAlign = taTrailing) và theo lý thuyết - nghĩ rằng đây sẽ là giải pháp. Các giá trị được cung cấp bởi hàm OnGetValue để điều khiển lưới. Tuy nhiên, vấn đề là mặc dù lúc đầu nó có vẻ OK, nếu bạn di chuyển thanh/con lăn chuột vv cột cột TColumn mới không xuất hiện để làm mới một cách chính xác bằng cách sử dụng phương pháp/mã dưới đây. Nó có thể là một lỗi/tính năng của Grid (hoặc cách tôi đang làm nó). Tôi đã thử .ReAlign vv ...; nhưng không có kết quả. Cách duy nhất để có được lưới trở lại trong dòng là làm một cột thay đổi kích cỡ ví dụ - mà sau đó vẽ lại chính xác?Điều khiển lưới Firemonkey - Căn chỉnh một cột sang bên phải

Đoạn mã dưới đây cho thấy rằng đó là một TGrid đơn giản, với 2 cols, 1 StringColumn chuẩn và 1 StringColNum mới của tôi (áp dụng căn chỉnh wuth đúng). - Bất kỳ trợ giúp nào được đánh giá cao vì điều này là yêu cầu cơ bản của bất kỳ công việc lưới điện nào.

unit Unit1; 

interface 

uses 
    System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, 
    FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.Objects, FMX.Grid, 
    FMX.Layouts, FMX.Edit; 

type 
    TForm1 = class(TForm) 
    Grid1: TGrid; 
    Button1: TButton; 
    StyleBook1: TStyleBook; 
    procedure Grid1GetValue(Sender: TObject; const Col, Row: Integer; 
     var Value: Variant); 
    procedure Button1Click(Sender: TObject); 
    private 
    { Private declarations } 
    public 
    { Public declarations } 
    end; 

    TStringColNum = class(TStringColumn) 
    private 
    function CreateCellControl: TStyledControl; override; 
    public 
    constructor Create(AOwner: TComponent); override; 
    published 
    end; 

var 
    Form1: TForm1; 

implementation 

{$R *.fmx} 

constructor TStringColNum.Create(AOwner: TComponent); 
begin 
    inherited; 
end; 

function TStringColNum.CreateCellControl: TStyledControl; 
var 
    t:TEdit; 
begin 
    Result:=TStringColNum.Create(Self); 
    Result.StyleLookup := 'textrightalign'; 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
begin 
    Grid1.AddObject(TStringColumn.Create(Self)); 
    Grid1.AddObject(TStringColNum.Create(Self)); // Right Aligned column? 

    Grid1.RowCount:=5000; 
    Grid1.ShowScrollBars:=True; 
end; 

procedure TForm1.Grid1GetValue(Sender: TObject; const Col, Row: Integer; 
    var Value: Variant); 
var 
    cell: TStyledControl; 
    t: TText; 
begin 
    if Col=0 then 
    Value:='Row '+IntToStr(Row);; 

    if Col=1 then 
    begin 
     cell := Grid1.Columns[Col].CellControlByRow(Row); 
     if Assigned(cell) then 
     begin 
      t := (Cell.FindStyleResource('text') as TText); 
      if Assigned(t) then 
      t.Text:='Row '+IntToStr(Row); 
     end; 
    end; 
end; 

end. 

Trân trọng. Ian.

Trả lời

5

Tất cả đều nhắc tôi rằng tôi vẫn chưa viết bài đăng blog của mình về điều này.

Dù sao, ô lưới có thể là hậu duệ của TStyledControl (về cơ bản là bất kỳ điều khiển nào). Mặc định cho một ô văn bản là TTextCell, chỉ đơn giản là một TEdit. Là một TEdit có nghĩa là thay đổi sự liên kết thực sự dễ dàng: chỉ cần thay đổi thuộc tính TextAlign. Không cần phải gây rối với phong cách (trừ khi bạn thực sự muốn).

Cột của bạn cần tạo các ô trong phương thức CreateCellControl. Bạn đang thực sự tạo ra một thể hiện của cột của bạn mà là vấn đề chính của bạn.

Bạn không cần phương thức Tạo cho cột của bạn (nó không làm gì cả), vì vậy hãy xóa nó (trừ khi bạn cần nó cho cái gì khác) và sửa đổi CreateCellControl của bạn.

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

Cuối cùng, GetValue nhu cầu xử lý sự kiện của bạn làm gì khác hơn là trả về giá trị:

procedure TForm1.Grid1GetValue(Sender: TObject; const Col, Row: Integer; 
    var Value: Variant); 
begin 
    if Col=0 then 
    Value:='Row '+IntToStr(Row); 

    if Col=1 then 
    Value := 'Row '+IntToStr(Row); 
end; 
+2

Cảm ơn Mike - Các "câu trả lời hoàn hảo" tôi đang tìm kiếm; một siêu sao thực sự ..! – Ian

0

Giảm dần cột không làm việc tốt với livebindings như bindmanager tạo ra các cột vì vậy bạn phải gây rối với giảm dần cái đó. Không thanh lịch cũng không thực tế trong quan điểm của tôi.

Chỉ cần căn chỉnh các ô của bạn trong sự kiện OnPainting lưới.

I := Col; 
for J := 0 to Grid1.RowCount - 1 do 
begin 
    T := TTextCell(Grid1.Columns[I].Children[J]); 
    T.TextAlign := TTextAlign.taTrailing; 
end; 
0

Nếu bạn sử dụng livebindings khi bạn có ít cơ hội tùy chỉnh lớp cột được tạo, nhưng bạn có thể tạo người trợ giúp cho cột đặt một số thuộc tính của điều khiển ô riêng lẻ. Không quá sang trọng nhưng đơn giản và hoạt động:

unit GridColumnHelper; 

interface 

uses 
    Fmx.Types, Fmx.Controls, Fmx.Grid, Fmx.Edit; 

type 
    TGridColumnHelper = class helper for TColumn 
    public 
    procedure SetEditMaxLength(aValue: Integer); 
    procedure SetEditTextAlign(aValue: TTextAlign); 
    end; 

implementation 

{ TGridColumnHelper } 

procedure TGridColumnHelper.SetEditMaxLength(aValue: Integer); 
var 
    lControl: TStyledControl; 
begin 
    for lControl in FCellControls do 
    begin 
    if lControl is TEdit then 
     (lControl as TEdit).MaxLength := aValue; 
    end; 
end; 

procedure TGridColumnHelper.SetEditTextAlign(aValue: TTextAlign); 
var 
    lControl: TStyledControl; 
begin 
    for lControl in FCellControls do 
    begin 
    if lControl is TEdit then 
     (lControl as TEdit).TextAlign := aValue; 
    end; 
end; 

end. 

Sau khi các ràng buộc đã điền lưới điện, bạn có thể gọi người giúp đỡ:

MyGrid.Columns[0].SetEditTextAlign(TTextAlign.taTrailing); 
MyGrid.Columns[1].SetEditMaxLength(15); 
0

Tôi nghĩ rằng đó là một sự lười biếng của Embarcadero.

thêm/sửa đổi 3 dòng trong FMX.Grid.pas giải quyết vấn đề này.

thay vì sửa đổi FMX gốc.Grid pas, tôi khuyên bạn nên sao chép bản gốc FMX.Grid pas vào thư mục Project của bạn, bao gồm trong Project của bạn (thêm vào Project) và thêm/modifiying các dòng sau.

TColumn = class(TStyledControl) 
    private const 
    HorzTextMargin = 2; 
    VertTextMargin = 1; 
    private 
    FReadOnly: Boolean; 
    FHorizontalAlign:TTextAlign;//Add this Line ********* 
    FEditMode: Integer; 
    FApplyImmediately: boolean; 
    ... 
    ... 
    procedure UpdateCell(ARow: Integer); 
    published 
    property HorizontalAlign: TTextAlign read FHorizontalAlign write FHorizontalAlign;//add this line ******* 
    property Align; 
    property ClipChildren default False; 

procedure TColumn.DefaultDrawCell(const Canvas: TCanvas; const Bounds: TRectF; const Row: Integer; 
    const Value: TValue; const State: TGridDrawStates); 
var 
    R: TRectF; 
    Layout: TTextLayout; 
    LocalRow: Integer; 
begin 
    if FDrawable <> nil then 
    FDrawable.DrawCell(Canvas, Bounds, Row, Value, State) 
    else 
... 
... 
     Layout.Opacity := AbsoluteOpacity; 
     (*remark this line ***************** 
     Layout.HorizontalAlign := Grid.TextSettingsControl.ResultingTextSettings.HorzAlign; 
     *) 
     Layout.HorizontalAlign := HorizontalAlign;//add this line ***** 

cuối cùng bạn có thể thiết lập thuộc tính mới trong dự án của bạn. ví dụ:

MyColumn.HorizontalAlign: = TTextAlign.taCenter;

0

Giải pháp "suat dmk" đang hoạt động tốt, bạn phải recompile Fmx.Bind.DBLinks.pas and Fmx.Bind.Editors.pas nếu bạn định sử dụng liên kết DB.

Sau đó, bạn chỉ cần đặt trong OnPainting sự kiện:

SGrid1.ColumnByIndex(1).HorizontalAlign := TTextAlign.Leading; 
Các vấn đề liên quan