列移动后的FMX TGrid OnGetValue(FMX TGrid OnGetValue after column moving)

我有Grid已启用列移动,代码:

type TRec = record Col0, Col1, Col2: string; end; var Data: TArray<TRec>; procedure TFormMain.GridGetValue(Sender: TObject; const Col, Row: Integer; var Value: TValue); begin case Col of 0: Value := Data[Row].Col0; 1: Value := Data[Row].Col1; 2: Value := Data[Row].Col2; end; end;

移动列时,此OnGetValue代码无法正常工作(显示以前位置的列数据)。 如何解决这个问题? 我应该使用OnColumnMoved事件并手动记住新列的位置吗?

I have Grid with enabled columns moving, and code:

type TRec = record Col0, Col1, Col2: string; end; var Data: TArray<TRec>; procedure TFormMain.GridGetValue(Sender: TObject; const Col, Row: Integer; var Value: TValue); begin case Col of 0: Value := Data[Row].Col0; 1: Value := Data[Row].Col1; 2: Value := Data[Row].Col2; end; end;

When column is moved this OnGetValue code works incorrectly (shown columns data on the previous positions). How to fix this? Should I use OnColumnMoved event and remember new columns position manually?

最满意答案

好的,这是我自己的答案:

我们应该为我们的TRec添加辅助函数,以便按索引读取字段:

type TRec = record Col0, Col1, Col2: string; function GetField(AIndex: Integer): string; end; function TRec.GetField(AIndex: Integer): string; begin case AIndex of 0: Result := Col0; 1: Result := Col1; 2: Result := Col2; else Result := ''; end; end;

还有2个使用Ini文件保存和恢复TGrid列的函数:

type TColumnData = record Pos: UInt8; Visible: Boolean; Width: UInt16; end; procedure LoadColumns(AGrid: TGrid; const ASection, AIdent: string); var I, J, ColsSize: Integer; A: TArray<TColumnData>; Col: TColumn; begin for I := 0 to AGrid.ColumnCount - 1 do AGrid.Columns[I].Tag := I; SetLength(A, AGrid.ColumnCount); ColsSize := AGrid.ColumnCount*SizeOf(TColumnData); if ReadIni(<FileName>, ASection, AIdent, (@A[0])^, ColsSize) = ColsSize then for J := 0 to AGrid.ColumnCount - 1 do begin for I := 0 to AGrid.ColumnCount - 1 do begin Col := AGrid.Columns[I]; if Col.Tag = A[J].Pos then begin Col.Index := J; Col.Visible := A[J].Visible; Col.Width := A[J].Width; end; end; end; end; procedure SaveColumns(AGrid: TGrid; const ASection, AIdent: string); var I, ColsSize: Integer; A: TArray<TColumnData>; Col: TColumn; begin SetLength(A, AGrid.ColumnCount); ColsSize := AGrid.ColumnCount*SizeOf(TColumnData); for I := 0 to AGrid.ColumnCount - 1 do begin Col := AGrid.Columns[I]; A[I].Pos := Col.Tag; A[I].Visible := Col.Visible; A[I].Width := Round(Col.Width); end; WriteIni(<FileName>, ASection, AIdent, (@A[0])^, ColsSize); end;

现在我们应该从OnFormCreate调用LoadColumns(它也为Columns初始化Tag字段)和OnFormDestroy中的SaveColumns。 最后是OnGetValue代码:

var Data: TArray<TRec>; procedure TFormMain.GridGetValue(Sender: TObject; const Col, Row: Integer; var Value: TValue); begin Value := Data[Row].GetField((Sender as TGrid).Columns[Col].Tag); end;

Ok, this is my own answer:

We should add helper function to our TRec for reading fields by index:

type TRec = record Col0, Col1, Col2: string; function GetField(AIndex: Integer): string; end; function TRec.GetField(AIndex: Integer): string; begin case AIndex of 0: Result := Col0; 1: Result := Col1; 2: Result := Col2; else Result := ''; end; end;

Also 2 functions to save and restore TGrid columns using Ini file:

type TColumnData = record Pos: UInt8; Visible: Boolean; Width: UInt16; end; procedure LoadColumns(AGrid: TGrid; const ASection, AIdent: string); var I, J, ColsSize: Integer; A: TArray<TColumnData>; Col: TColumn; begin for I := 0 to AGrid.ColumnCount - 1 do AGrid.Columns[I].Tag := I; SetLength(A, AGrid.ColumnCount); ColsSize := AGrid.ColumnCount*SizeOf(TColumnData); if ReadIni(<FileName>, ASection, AIdent, (@A[0])^, ColsSize) = ColsSize then for J := 0 to AGrid.ColumnCount - 1 do begin for I := 0 to AGrid.ColumnCount - 1 do begin Col := AGrid.Columns[I]; if Col.Tag = A[J].Pos then begin Col.Index := J; Col.Visible := A[J].Visible; Col.Width := A[J].Width; end; end; end; end; procedure SaveColumns(AGrid: TGrid; const ASection, AIdent: string); var I, ColsSize: Integer; A: TArray<TColumnData>; Col: TColumn; begin SetLength(A, AGrid.ColumnCount); ColsSize := AGrid.ColumnCount*SizeOf(TColumnData); for I := 0 to AGrid.ColumnCount - 1 do begin Col := AGrid.Columns[I]; A[I].Pos := Col.Tag; A[I].Visible := Col.Visible; A[I].Width := Round(Col.Width); end; WriteIni(<FileName>, ASection, AIdent, (@A[0])^, ColsSize); end;

Now we should call LoadColumns (which is also initialize Tag fields for Columns) from OnFormCreate and SaveColumns from OnFormDestroy. And finally OnGetValue code:

var Data: TArray<TRec>; procedure TFormMain.GridGetValue(Sender: TObject; const Col, Row: Integer; var Value: TValue); begin Value := Data[Row].GetField((Sender as TGrid).Columns[Col].Tag); end;

更多推荐