Select Cell in TAdvStringGrid with hidden columns - delphi

I am selecting a certain cell in a TAdvStringGrid:
const
MyCol=4;
MyRow=1;
HiddenCol=2;
procedure TForm1.FormCreate(Sender: TObject);
begin
AdvStringGrid1.ColCount:=5;
AdvStringGrid1.RowCount:=10;
end;
procedure TForm1.BtnHideClick(Sender: TObject);
begin
AdvStringGrid1.HideColumn(2);
end;
procedure TForm1.BtnSelectCellClick(Sender: TObject);
begin
AdvStringGrid1.SelectCells(MyCol,MyRow,MyCol,MyRow);
end;
However, my problem is that after the column is hidden, the cell I need to be selected won't be selected, since the program is seeing that the ColCount is now 4 and the cell at col 5 no more exists. How can I still select the cell regardless the hidden column?
By selecting I mean to focus the cell, and show the user what cell is been selected, not just read its string value.

According to the TAdvStringGuide v6.1 Developers Guide on page 57, you can use grid.AllCells(ACol, ARow). The description says:
"Access the grid cell as string irrespective of hidden columns or rows. grid.AllCells returns the cell as displayed, ie. after possible processing of the real cell text by the event OnGetDisplText".
To show the selected cell, you could make use of some additional functions they give you. From page 131 in their guide:
TAdvStringGrid also provides a set of functions to allow performing the mapping of real cell indexes to visible cells indexes and vice versa. This is provided through:
function RealRowIndex(ARow: Integer): Integer;
function RealColIndex(ACol: Integer): Integer;
Returns the real column or row index for a given visible column or row index
function DisplRowIndex(ARow: Integer): Integer;
function DisplColIndex(ACol: Integer): Integer;
Returns the visible column or row index for a given real column or row index.
So I think you might find what you are looking for by changing your last method to:
procedure TForm1.BtnSelectCellClick(Sender: TObject);
begin
AdvStringGrid1.SelectCells(DisplColIndex(MyCol),DisplRowIndex(MyRow),DisplColIndex(MyCol),DisplRowIndex(MyRow));
end;

Related

Delphi: Bind a Chart with a DBGrid

I want to bind a Chart with a DBGrid.
Refer to the exhibit.
When I click in the DBGrid on number 3 (X-Axis), then the bar at position three should be highlighted(or a pointer to bar 3).
When I click on number 4 in the Grid then bar 4 is highlighted etc.
I'm using a TDBChart
Is there a way to do this?
Not knowing what the charting component is, cannot provide a working example, but the key which you are looking for is to use the AfterScroll event for the dataset in the grid. Since each row represents a different record, that event is fired when the grid selection moves to the row.
Edit: This doesn't highlight with a box, but does change the color of the value marks at the top of each bar. Hopefully this gets you on your way. MyQuery is what is feeding the datasource
var
savecolor : tcolor;
procedure MyForm.FormShow(Sender:TObject);
begin
...
SaveColor := dbchart1.series[0].marks.items[0].color;
...
end;
procedure MyForm.MyQueryBeforeScroll(DataSet : TDataSet);
begin
dbchart1.series[0].marks.items[MyQuery.recno-1].color := SaveColor;
end;
procedure MyForm.MyQueryAfterScroll(DataSet:TDataSet);
begin
dbchart1.series[0].marks.items[MyQuery.recno-1].color := clRed;
end;

TStringGrid: Is it possible to find out the 'State' of a cell?

I want to implement a FillCell procedure for TStringGrid. I want to fill a certain cell with a color but only when the cell (row) is not selected.
procedure TMyStrGrid.FillCell(Rect: TRect; aColor: TColor);
begin
//if NOT (gdSelected in State) then <---- how do I obtain the 'State' here?
begin
Canvas.Brush.Color:= aColor;
Canvas.FillRect(Rect);
end;
end;
This is just an exercise :) I am trying to figure out VCL.Grids.pas which is quite complex.
According to the comments, you are calling this function from an OnDrawCell handler. That OnDrawCell handler is passed a TGridDrawState argument which specifies whether or not the cell is selected. The event handler is of this form:
TDrawCellEvent = procedure (Sender: TObject; ACol, ARow: Longint;
Rect: TRect; State: TGridDrawState) of object;
You are asking whether it is possible to ignore the TGridDrawState and somehow recover the information later. In principle it is possible:
You have available the row and column. That identifies the cell and you can check whether or not the cell is in the current selection.
If you want to ignore the row and column also, then you could inspect the TRect that is supplied. Map that back to the row and column and again check that against the current selection.
Frankly what you are trying to do is silly in my view. You have been supplied with the draw state for a good reason. It has the information you need. Use it.

Delphi, Show button in a different TGridPanelLayout cell

Hi I am working with XE6 and I am using a TGridPanelLayout with 4 col and 4 rows. On the first cell I am displaying a Button. What I would like to do is, that when I click on this Button, get that Button to appear in a different cell. But I cannot find how to do it, so far I tried this, but nothing happens.
procedure TForm4.Button1Click(Sender: TObject);
begin
GridMyPannel.ControlCollection.BeginUpdate;
GridMyPannel.ControlCollection.AddControl(Button1, 2, 2);
Button1.Parent := GridMyPannel;
end;
I am really new on Delphi. Could anyone give me an example of how I could do it?
A TGridPanel has a ControlCollection property which allows access to the Row and Column properties that also appear on your TButton once you've placed in inside your TGridpanel. A TButton (or rather its superclass TControl) does not have a Row or Column property. So we need to get a grip of the TControlItem wrapper the TGridpanel uses.
procedure TForm8.Button1Click(Sender: TObject);
var
selectedControl: TControl;
itemIndex: Integer;
selectedControlItem: TControlItem; // This knows about "Row" and "Column"
begin
// This is the button we've clicked
selectedControl := Sender as TControl;
itemIndex := GridPanel1.ControlCollection.IndexOf(selectedControl);
if (itemIndex <> -1) then begin
selectedControlItem := GridPanel1.ControlCollection.Items[itemIndex];
selectedControlItem.Row := Random(GridPanel1.RowCollection.Count);
selectedControlItem.Column := Random(GridPanel1.ColumnCollection.Count);
end;
end;
The above code finds the button and changes its Row and Column property to a random value. Note that you didn't specify whether the TButton is the only control within the TGridpanel. Is that the case?
I did the below in normal VCL and XE3 and with a TGridPanel (no TGridPanelLayout in my Delphi).
The problem with the GridPanel is that it does not allow controls (Buttons, etc) to be placed in any cell (like Cell:1,1) without having controls in the cells before that cell. GridPanel always fills itself from Index 0 upwards.
So the trick is to fool it. Now depending on whether you already have other cells in the GridPanel you will have to make place for the button to go to and also put something else in its place if the button was in a cell of lower index.
Have a look at the form before the button is pressed:
Note that I have not created a ControlItem at cell 1,0 yet.
I want to move Button 1 to cell 1,0. I cannot do that unless I first place something else in its place (cell 0,0). I have to create a new ControlItem at cell 1,0 to house button1.
procedure TForm1.Button1Click(Sender: TObject);
begin
// Places CheckBox1 in the same cell as BUtton1
GridPanel1.ControlCollection.ControlItems[0,0].Control := CheckBox1;
// Create a new ControlItem for Button1 and in the same breath move
// Button1 to it
GridPanel1.ControlCollection.AddControl(Button1,1,0);
// You know what this does. :)
CheckBox1.Parent := GridPanel1;
end;
The result:

How can I select multiple individual cells of a string grid?

I am looking for a string grid that allows me select multiple cells anywhere in the grid without them adjoining each other, e.g pressing CTRL and clicking on various cells over the grid. Or if anyone knows how to do this with the standard Delphi TStringGrid.
Any pointer would be gratefully received.
Although there are a lot of better capable people here, since you haven't gotten any answers, I thought I'd give it a try.
I'm not aware of a way to have the component do this for you. However, when you Control-click a cell, the event OnSelectedCell is called. (I just tested that.) You could put code in an event handler that adds the cell's row and column to a list that you keep of the rows and columns that are selected. Then, in the OnDrawCell event, highlight the cell:
procedure TForm1.StringGrid1DrawCell( Sender: TObject;
ACol: Integer;
ARow: Integer;
Rect: TRect;
State: TGridDrawState);
begin
if CellSelected( ARow, ACol) then // you write CellSelected() to refer to the list you're keeping
begin
StringGrid1.Canvas.Brush.Color := clYellow;
StringGrid1.Canvas.FillRect(Rect);
StringGrid1.Canvas.TextOut(Rect.Left,Rect.Top,StringGrid1.Cells[ACol,ARow]);
end;
end;

DBGrid get selected cell

I need to get the value of the selected cell of a DBGrid in Delphi.
I have no idea how to do it. I tried dbGrid's OnMouseMove
pt : TGridCoord;
...
pt:=dbGrid.MouseCoord(x, y);
[Edited]
I can use the OnCellClick to get the value of the cell with "Column.Field.AsString", but I want to get the value from the first column when I click on any column of that row.
Found it.
dbGrid.Fields[0].AsString gets the value of the first column of the selected row.
procedure TForm1.DBGrid_DrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumnEh; State: TGridDrawState);
const defaultCheckBoxFieldNumber = 1;
begin
if DBGrid.SelectedField.FieldNo = defaultCheckBoxFieldNumber then
....;
else
...;
end;
DBGrid.SelectedField.FieldNo gets selected field on event DrawColumnCell in TDBGrid.
I know this is late and not sure if it is what the title means.
But if it means to get the selected cell value, then try this:
procedure Form1.dbGrid1CellClick(Column: TColumn);
begin
ShowMessage(table1.Fields[Column.Index].AsString);
end;
Make sure
dbGrid1.Options.dbRowSelect := False;
i think the easiest way is to connect a hidden DBText to your dataset then set the DBText to display which field you need, this way that DBText will always contain the needed value of the active record
A DBGrid has no focus, and therefore you cannot find out which row is seleted. Instead look at the linked DataSet. A DataSet has an active row.
try this to get the value of selected cell in dbgrid:
procedure Form1.dbGrid1CellClick(Column: TColumn);
begin
ShowMessage(table1.Fields[DBGrid1.SelectedIndex].AsString);
end;

Resources