所以我有一个带有列的字符串网格。但是可以删除每列,如果删除列,则重新排列索引。我可以在删除之前使用索引的值,但是当删除多个列时,索引根本就不相同。例如,如果我删除索引1和2处的列,则索引为3的列将获得一个新索引,索引为1。
所以我想要做的是在我的列中添加新方法,我将设置并获取真正的索引,因为它从未被删除。我找到了一个关于如何向delphi类添加新方法的教程,这就是它的外观:
unit columnInterceptor
interface
uses stdCtrls, sysUtils, Classes, dialogs, grids;
type
TStrings = class(Classes.TStrings)
private
public
procedure hello;
end;
implementation
procedure TStrings.Hello;
begin
ShowMessage('hello');
end;
end.
如果我使用它在StringGrid上添加方法,这是有效的。但我想在stringGrid的列上使用它。我已经看到一些方法来自TStrings或TObject类,我试过它们但是程序你好并没有显示出来。
修改
使用类帮助程序我设法可以访问我自己的方法,在更改之后它的外观如下:
unit columnInterceptor
interface
uses stdCtrls, sysUtils, Classes, dialogs, grids;
type
colIntercept= class helper for TStrings
public
procedure setValue(val: integer);
function getValue: integer;
end;
implementation
var
value : integer;
procedure colIntercept.setValue(val: integer);
begin
value := integer;;
end;
function colIntercept.getValue: integer;
begin
Result := value;
end;
end.
事情是,如果我添加一个私人声明,我不能再使用我的方法,这些方法在公共声明中声明。当我设置一个值时,它对所有列实际上是相同的。这是我使用这个类的方式:
//somewhere in the unit where create all the columns
grid.Cols[aCol].setValue(aCol);
//somewhere in the unit
grid.Cols[aCol].getValue
然后任何列的所有值都始终相同。当我设定我的价值时,他们每次都是不同的。但是获取它们,总是返回我使用setValue方法插入的最后一个值。
答案 0 :(得分:0)
问题是StringGrid.Cols不是TStrings而是TStrings的后代。
您可以尝试以下代码:
ShowMessage(StringGrid1.Cols[0].Classname);
然后你会发现真正的类是TStringGridStrings
因此,这引出了解决方案:
为TStringGridStrings写一个classhelper
type
TStringGridStringsHelper = class helper for TStringGridStrings
procedure SayHello;
end;
{ TStringGridStringsHelper }
procedure TStringGridStringsHelper.SayHello;
begin
ShowMessage('Hello from TStringGridStringsHelper');
end;
但仍然无法写
StringGrid1.Cols[0].SayHello;
你必须对它进行类型转换:
TStringGridStrings(StringGrid1.Cols[0]).SayHello;
问题是StringGrid只将它的列公开为TStrings,而不是正确的数据类型TStringGridStrings,这就是你必须输入它的原因
<强> ===================== 强>
另一个解决方案可能是使用检查员类(http://delphi.about.com/od/delphitips2009/qt/interceptor.htm),但有些人说这是错误的代码:
以下是示例:
unit Unit6;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, Grids;
type
TStringGridStringsHelper = class helper for TStringGridStrings
procedure SayHello;
end;
TStringGrid = class(Grids.TStringGrid)
strict private
function GetCols(Index: Integer): TStringGridStrings;
function GetRows(Index: Integer): TStringGridStrings;
procedure SetCols(Index: Integer; const Value: TStringGridStrings);
procedure SetRows(Index: Integer; const Value: TStringGridStrings);
public
property Cols[Index: Integer]: TStringGridStrings read GetCols write SetCols;
property Rows[Index: Integer]: TStringGridStrings read GetRows write SetRows;
end;
TForm6 = class(TForm)
StringGrid1: TStringGrid;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form6: TForm6;
implementation
{$R *.dfm}
uses
Math;
{ TStringGridStringsHelper }
procedure TStringGridStringsHelper.SayHello;
begin
ShowMessage('Hello from TStringGridStringsHelper');
end;
procedure TForm6.FormCreate(Sender: TObject);
begin
StringGrid1.Rows[0].SayHello;
end;
{ TMyStringGrid }
function TStringGrid.GetCols(Index: Integer): TStringGridStrings;
begin
Result := inherited Cols[Index] as TStringGridStrings;
end;
function TStringGrid.GetRows(Index: Integer): TStringGridStrings;
begin
Result := inherited Rows[Index] as TStringGridStrings;
end;
procedure TStringGrid.SetCols(Index: Integer; const Value: TStringGridStrings);
begin
inherited Cols[Index] := Value;
end;
procedure TStringGrid.SetRows(Index: Integer; const Value: TStringGridStrings);
begin
inherited Rows[Index] := Value;
end;
end.
答案 1 :(得分:0)
关于你的编辑,你有一个变量,所以对你的帮助者的任何访问权都可以读/写。
虽然可以使用帮助程序类保存Col的索引 ,它并没有真正帮助,因为col的“内容”被“移动”到另一个 内部cols是指向TSparseList的TSparsePointerArray中的条目的指针指针
以下代码并不意味着建立这样的帮助作为推荐,但仅用于说明目的。
implementation
uses system.generics.collections;
{$R *.dfm}
type
THackGrid=Class(TCustomGrid);
TSLDict=Class(TDictionary<TStrings,Integer>)
End;
TStringsHelper = class helper for TStrings
private
class var Dict:TSLDict;
function GetIndex: Integer;
procedure SetIndex(const Value: Integer);
public
CLASS Procedure FreeDict;
Property Index:Integer Read GetIndex write SetIndex;
end;
{ TStringsHelper }
CLASS procedure TStringsHelper.FreeDict;
begin
FreeAndNil(Dict);
end;
function TStringsHelper.GetIndex: Integer;
begin
if not assigned(Dict) then Dict:=TSLDict.Create;
if not Dict.TryGetValue(self,Result) then Result := -1;
end;
procedure TStringsHelper.SetIndex(const Value: Integer);
begin
if not assigned(Dict) then Dict:=TSLDict.Create;
Dict.AddOrSetValue(self,Value);
end;
procedure TForm7.DeleteAColClick(Sender: TObject);
var
I:Integer;
begin
for I := 0 to StringGrid1.ColCount - 1 do
begin
StringGrid1.Cells[i,0] := IntToStr(i);
StringGrid2.Cells[i,0] := IntToStr(i);
StringGrid1.Cols[i].Index := i;
end;
for I := 0 to StringGrid1.ColCount - 1 do
begin
StringGrid1.Cells[i,1] := IntToStr(StringGrid1.Cols[i].Index);
StringGrid1.Cells[i,2] := '$'+IntToHex(Integer(StringGrid1.Cols[i]),8);
StringGrid2.Cells[i,1] := IntToStr(StringGrid1.Cols[i].Index);
StringGrid2.Cells[i,2] := '$'+IntToHex(Integer(StringGrid1.Cols[i]),8);
end;
THackGrid(StringGrid1).DeleteColumn(2);
THackGrid(StringGrid1).DeleteColumn(1);
for I := 0 to StringGrid1.ColCount - 1 do
begin
StringGrid1.Cells[i,3] := IntToStr(StringGrid1.Cols[i].Index);
StringGrid1.Cells[i,4] := '$'+IntToHex(Integer(StringGrid1.Cols[i]),8)
end;
end;
procedure TForm7.MoveAColClick(Sender: TObject);
var
I:Integer;
begin
for I := 0 to StringGrid1.ColCount - 1 do
begin
StringGrid1.Cells[i,0] := IntToStr(i);
StringGrid2.Cells[i,0] := IntToStr(i);
StringGrid1.Cols[i].Index := i;
end;
for I := 0 to StringGrid1.ColCount - 1 do
begin
StringGrid1.Cells[i,1] := IntToStr(StringGrid1.Cols[i].Index);
StringGrid1.Cells[i,2] := '$'+IntToHex(Integer(StringGrid1.Cols[i]),8);
StringGrid2.Cells[i,1] := IntToStr(StringGrid1.Cols[i].Index);
StringGrid2.Cells[i,2] := '$'+IntToHex(Integer(StringGrid1.Cols[i]),8);
end;
THackGrid(StringGrid1).MoveColumn(0,3);
for I := 0 to StringGrid1.ColCount - 1 do
begin
StringGrid1.Cells[i,3] := IntToStr(StringGrid1.Cols[i].Index);
StringGrid1.Cells[i,4] := '$'+IntToHex(Integer(StringGrid1.Cols[i]),8)
end;
end;
procedure TForm7.MoveFirstAndDeleteThenClick(Sender: TObject);
var
I:Integer;
// we want to delete Col 1
begin
for I := 0 to StringGrid1.ColCount - 1 do
begin
StringGrid1.Cells[i,0] := IntToStr(i);
StringGrid1.Cols[i].Index := i;
end;
for I := 0 to StringGrid1.ColCount - 1 do
begin
StringGrid1.Cells[i,1] := IntToStr(StringGrid1.Cols[i].Index);
end;
THackGrid(StringGrid1).MoveColumn(1,StringGrid1.ColCount-1);
THackGrid(StringGrid1).DeleteColumn(StringGrid1.ColCount-1);
for I := 0 to StringGrid1.ColCount - 1 do
begin
StringGrid1.Cells[i,2] := IntToStr(StringGrid1.Cols[i].Index);
end;
end;
initialization
finalization
TStrings.FreeDict;
如果我们删除Col 1和Col 2的结果: