Delphi, expand grouped by grid by default - delphi

I have this procedure for a grid in Delphi, and I need to add this property to expand all collapsed grouped by data in the grid.
procedure TProjectForm.dxDBGridEventDrawCell(
Sender: TcxCustomGridTableView; ACanvas: TcxCanvas;
AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean);
begin
inherited;
DrawHighlight(ACanvas);
TcxGridDbTableView.ViewData.Expand(True);
end;
I get the following error:
E2233 Property 'ViewData' inaccessible here
Help is appreciated please. And I also need to remove the collapsible button for the grouped data in this grid. Thank you

You can call cxGrid1DBTableView1.ViewData.Expand(True) without problems as long as you don't do in in a drawing event like the one in your q. However, you don't actually need to do this if you use the example below.
This works fine
procedure TDevexGroupingForm.FormCreate(Sender: TObject);
begin
cxGrid1DBTableView1.Columns[2].GroupIndex := 0; // group by the 3rd column
// NOTE: this step is only necessary if the table view has not been grouped at design-time
cxGrid1DBTableView1.DataController.Options := cxGrid1DBTableView1.DataController.Options
+ [dcoGroupsAlwaysExpanded]; // this hides the +/- buttons of the grouped nodes
cxGrid1DBTableView1.DataController.FocusedRowIndex := 0; // focuses the first group
end;
Note : This has been updated at #Nil's suggestion.
The first line, setting a column's GroupIndex is only necessary if the TableView has not already been grouped at design time.
Setting the FocusedRowIndex is optional, depending on how you want the TableView to display initially
So in fact the hiding of the +/- grouping buttons and the expansion of all the top-level group nodes can be achieved by the single step of setting the DataController Options property to include the dcoGroupsAlwaysExpanded option.
Btw Setting the DataController options to suppress the drawing of the expand/collapse buttons and is derived from the article https://www.devexpress.com/Support/Center/Question/Details/Q105527/how-do-i-hide-the-expand-button-on-a-grid

Related

How to adjust row height of DBGrid - Delphi

I have a DBGrid that receives data from an ADOTable in a data module for my project, but I noticed the text or fields of the records do not display fully. The bottom part of a "g" would be cut off due to the small row height. How do I code to change this?
I know you can change column widths. Could one do something similar for rows as well?
The only way you can do this at design-time is to define your own TDBGrid descendant, add a RowHeight property to it and install it in the IDE.
The following will work at run-time:
type
TMyDBGrid = class(TDBGrid);
procedure TForm1.Button1Click(Sender: TObject);
begin
TMyDBGrid(DBGrid1).DefaultRowHeight := 32;
end;
This works because DefaultRowHeight is a protected property of TCustomGrid, from which TDBGrid descends.

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;

TcxGrid Auto posting if another row is focused?

I'm using Delphi the devexpress components.
I'm running into a annoying problem where the grid seems to call a postdata if I'm inserting a new row and then accidently click on a different row.
I'm not sure the TcxGrid is doing this but I want to know if there is a property I could set to prevent this from happening?
As fas as this is not a problem of the grid, but of the dataset, the only way to intervene is preveting a post for conditions you have to define.
procedure TForm.aDatasetBeforePost(DataSet: TDataSet);
begin
if YourConditionForInvaliddata then
begin
Dataset.Cancel;
Abort;
end;
end;

Live update of StringGrid when horizontal scroll bar is moving?

In Delphi 2010, I need to display a grid that has a horizontal scroll bar with about 15 columns x 5 rows.
I chose to use a StringGrid.
However, while the mouse button is down dragging the horizontal scroll bar, I want the grid to scroll live.
The StringGrid component, it appears, does not scroll live. It waits until the mouse button is released before updating the column and scrolling if necessary.
Also, the horizontal scroll bar button (is that what it's called) is not proportional to the number of columns. And for a down-arrow when on the bottom row to move to the top of the next column to the right...
These seem like common needs, so I was surprised not to find them in TStringGrid.
Any suggestions on a way around these two problems? I can use a DbGrid or other standard component, but my preference is to not use a commercial grid if I can avoid it. And I'm not going to use shareware or freeware...
TIA
For the first question, you can set goThumbTracking in the StringGrid's Options at design-time, or at run-time: StringGrid1.Options := StringGrid1.Options + [goThumbTracking];
For the third question, you can provide the functionality you need by using keyboard event handlers of the control. An example;
procedure TForm1.StringGrid1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
var
StringGrid: TStringGrid;
begin
StringGrid := Sender as TStringGrid;
case Key of
VK_DOWN:
if StringGrid.Row = StringGrid.RowCount - 1 then begin
Key := 0;
StringGrid.Row := StringGrid.FixedRows;
if StringGrid.Col = StringGrid.ColCount - 1 then
StringGrid.Col := StringGrid.FixedCols
else
StringGrid.Col := StringGrid.Col + 1;
end;
VK_UP: //...;
VK_RIGHT: //;
VK_LEFT: //;
end;
end;
For the second question, the scrolling code seems to be buried in private methods of TCustomGrid. I have no clue how to achieve that..
If noticed you are not interested in third party components - Freeware, I am not fond of these either, but we all must make sacrifices sometimes if we want to get the problems solved. This is one of these sacrifices! This component is to good to be ignored. You will not create something like it yourself if you don't have a couple of years of free time.
Either write a new component based on TStringGrid (I would not - it is not the best tool in the box to begin with)
But take some time and learn TVirtualStringTree. The component is years ahead of TStrignGrid. The source is available and there are many who uses it.
And there are events already implemented to react on scrollbar changes
OnScroll, OnShowScrollbar
http://www.delphi-gems.com/index.php?option=com_content&task=view&id=12&Itemid=38
Search on stackoverflow and you can read much more about tvirtualstringtree
Second the suggestion to use TVirtualStringTree. Working with the TStringGrid component is like stabbing yourself in the belly with a rusty scissor.

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;

Resources