So I have a string grid with columns. But each column can be deleted and if a column is deleted indexes are rearranged. I can use the value of my index before deletion, but when it comes to delete several columns the indexes aren't the same at all. For example if i delete the column at index 1 and 2, the one that was at index 3 get a new index, index 1.
So what I want to do is to add new methods to my columns where i will set and get the real index, as it was never deleted. I have found a tutorial on how to add new methods to delphi classes and this is how it looks:
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.
This works if i use it to add methods on a StringGrid. But i want to use this on a Column of a stringGrid. I've seen that some methods are coming from the class TStrings or TObject, and i tried them both but the procedure hello doesn't show.
EDIT
Using class helper i managed to have access to my own method and after changing this is how it looks:
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.
Thing is that if i add a private statement i can't use my methods anymore which are declared in public statement. And when i set a value it's actually the same for all columns. This is how i uses this class:
//somewhere in the unit where create all the columns
grid.Cols[aCol].setValue(aCol);
//somewhere in the unit
grid.Cols[aCol].getValue
And then all the value for any column is always the same. When i'm setting my values they are different each time. But getting them, returns me always the last value i inserted using setValue method.
Regarding to your edit, you have got one variable so any access to your helper will read/write on this.
Although it is possible to save the index of a Col with a helper class
, it does not really help because the "content" of a col is "moved" to another one.
Internal cols is a casted Pointer to an entry in an TSparsePointerArray of a TSparseList
Below standing code is not meant to build such a helper as a recommendation, but for illustrative purposes only.
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;
The result if we delete Col 1 and Col 2: