XE StringGrid应用(G1属性触发G2)
unit UnitMain; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, System.Rtti, FMX.StdCtrls, FMX.Grid, FMX.Layouts, FMX.Controls.Presentation, FMX.Edit; type TForm8 = class(TForm) Edit1: TEdit; G1: TStringGrid; G2: TStringGrid; StringColumn1: TStringColumn; StringColumn2: TStringColumn; Button1: TButton; Button2: TButton; procedure FormActivate(Sender: TObject); procedure G1SelectCell(Sender: TObject; const ACol, ARow: Integer; var CanSelect: Boolean); procedure G2SelectCell(Sender: TObject; const ACol, ARow: Integer; var CanSelect: Boolean); procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private FRow2: Integer; FRow1: Integer; { Private declarations } procedure ShowG1(); // 显示表1 procedure ShowG2(); // 显示表2数据 procedure Item(); // 显示Edit等数据 procedure Save(); // 保存数据 procedure SetRow1(const Value: Integer); procedure SetRow2(const Value: Integer); public { Public declarations } property Row1 : Integer read FRow1 write SetRow1; // 表1属性,OnSelectCell属性触发,改变时do something property Row2 : Integer read FRow2 write SetRow2; // 表1属性,OnSelectCell属性触发,改变时do something end; var Form8: TForm8; implementation {$R *.fmx} procedure TForm8.Button1Click(Sender: TObject); begin G2.RowCount:=G2.RowCount+1; // 动态改变G2的Row G2.Cells[0,G2.RowCount-1]:='aa'; end; procedure TForm8.Button2Click(Sender: TObject); begin Edit1.Text := FROW2.ToString ; end; procedure TForm8.FormActivate(Sender: TObject); begin if(Tag=0) then begin Tag:=1; FRow1:=-1; FRow2:=-1; ShowG1(); if(g1.RowCount>0) then G1.SelectCell(0,0); // 初始化时,选中G1的第一行 end; end; procedure TForm8.ShowG1; var ss: TStringList; i: Integer; begin ss:=TStringList.Create; ss.LoadFromFile('c:/g1.txt'); G1.RowCount:=ss.Count; for i:=0 to ss.Count-1 do G1.Cells[0,i]:=ss[i]; ss.Free; end; procedure TForm8.ShowG2; var ss: TStringList; i: Integer; begin ss:=TStringList.Create; ss.LoadFromFile('c:/g2'+FRow1.ToString+'.txt'); G2.RowCount:=ss.Count; for i:=0 to ss.Count-1 do G2.Cells[0,i]:=ss[i]; ss.Free; FRow2:=-1; if(G2.RowCount>0) then begin Row2:=0; G2.SelectCell(0,0); end; end; procedure TForm8.Item; begin Edit1.Text:=G2.Cells[0,Row2]; end; procedure TForm8.Save; var ss:TStringList; i:Integer; begin if(FRow2>=0) and (FRow2<=G2.RowCount-1) then begin if(Edit1.Text<>G2.Cells[0,FRow2]) then begin G2.Cells[0,FRow2]:=Edit1.Text; ss:=TStringList.Create; for i:=0 to G2.RowCount-1 do ss.Add(G2.Cells[0,i]); ss.SaveToFile('c:/g2'+FRow1.ToString+'.txt'); ss.Clear(); for i:=0 to G1.RowCount-1 do ss.Add(G1.Cells[0,i]); ss.SaveToFile('c:/g1.txt'); ss.Free; end; end; end; procedure TForm8.SetRow1(const Value: Integer); begin if(Value<>FRow1) then begin Save(); FRow1 := Value; G1.SelectCell(0,Value); ShowG2(); end; end; procedure TForm8.SetRow2(const Value: Integer); begin if(Value<>FRow2) then begin Save(); FRow2 := Value; Item(); end; end; procedure TForm8.FormCloseQuery(Sender: TObject; var CanClose: Boolean); begin Save(); CanClose:=True; end; procedure TForm8.G1SelectCell(Sender: TObject; const ACol, ARow: Integer; var CanSelect: Boolean); begin // 鼠标点击空白地方的时候,会触发该事件,而ARow的值超出范围 CanSelect:=False; if(ARow>=0) and (ARow<=G1.RowCount-1) then begin if(Row1<>ARow) then Row1:=ARow; CanSelect:=True; end; end; procedure TForm8.G2SelectCell(Sender: TObject; const ACol, ARow: Integer; var CanSelect: Boolean); begin CanSelect:=False; if(ARow>=0) and (ARow<=G2.RowCount-1) then begin if(Row2<>ARow) then Row2:=ARow; CanSelect:=True; end; end; end.
XE中StringGrid控件还是有很多bug的,在OnSelectCell事件里,鼠标滑过也会触发,若要用ShowMessage或弹出模态窗体,Grid重新聚焦时,会频繁的触发。
在鼠标滑过没有行的Index位置时,也会触发OnSelectCell事件,会出现Index超界,报错。
所以每次都必须保证Grid里有数据,(ARow>=0) and (ARow<=G2.RowCount-1)