Delphi: Bind a Chart with a DBGrid - delphi

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;

Related

Procedure to change the color of multiple panels with different names in Delphi

I have a TForm with 5 TPanel controls on it. I need them to change color when they are clicked on.
I can easily write code for each TPanel to change colors, but that consists of too much code, so I was wondering if I could write a procedure to change the color of each one independently and just call this function with the name of each TPanel as a parameter? If not, then is there any other way to do this?
This is really easy.
Create a new VCL application.
Add five TPanel controls to the main form.
Select all five panels.
In the Object Inspector, set ParentBackground to False.
In the Object Inspector, click the Events tab and click the empty field to the right of the OnClick row caption. Type PanelClick and press Enter.
Write the following code:
procedure TForm1.PanelClick(Sender: TObject);
begin
if Sender is TPanel then
TPanel(Sender).Color := RGB(Random(255), Random(255), Random(255));
end;
I think this is what you asked. However, given your image, I suspect you rather would like a toggling behaviour:
procedure TForm1.PanelClick(Sender: TObject);
var
i: Integer;
begin
for i := 0 to ControlCount - 1 do
if Controls[i] is TPanel then
if Controls[i] = Sender then
TPanel(Controls[i]).Color := clHighlight
else
TPanel(Controls[i]).Color := clBtnFace;
end;
This iterates over the child controls of Self, since ControlCount and Controls mean Self.ControlCount and Self.Controls, respectively. If your target panels have a different parent (a panel, say), iterate over its children instead.
Optionally, you can give the target panels a specific Tag value (like 500) and only change the colour of such panels.
And please set BevelOuter to bvNone. We have left the 90s.

Delphi, expand grouped by grid by default

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

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:

Delphi Listview leaves selection marks behind [duplicate]

I am using listview in vsreport virtual mode, have two columns and after I populate the list, select one row, and then select some other row there's an artifact left on a previously selected row, see image below. How to fix this?
and this is my code that gets the data from an array
procedure TForm1.ListView1Data(Sender: TObject; Item: TListItem);
begin
Item.Caption := FloatToStr(Item.Index + 1);
Item.SubItems.Add(FloatToStr(a[Item.Index]));
end;
When I hover the mouse, the artifacts dissapear.
Thanks
Setting the listview's DoubleBuffered property to true solves the artifacts problem.

hyperlink field in DBGRID

I'm doing a small internal software to search branch lines in my company. In addition to the branch lines I also put an e-mail field in the database as shown below:
My intention is to click on the registered e-mail and the software via the ShellExecute open a window to send the e-mail. I'm using the option dgRowSelect as TRUE and because of that the OnCellClick event does not correctly identify which cell was clicked.
In my searches have not found any way to do this. Then I thought of using a TLabel within the field. I can use the onclick event in the TLabel and also change the cursor icon.
If TLabel is a good solution, how can I add a TLabel in DBGrid?
Or what would be another good solution?
I'm guessing that purpose of dgRowSelect=true is for highlighting whole selected row.
TLabel is not the way I would go - I would set dgRowSelect=false and paint selected row in OnDrawColumnCell or create my own fixed dbgrid.
There was a similar question:
how can i colour whole row in DBGrid with rowselect turned off?
Anyway if you want to use dgRowSelect=true and get valid info about clicked cell, here it is:
type THackDBGrid=class(TDBGrid);
procedure TForm1.dbgrd1CellClick(Column: TColumn);
var p:TPoint;
col:TGridCoord;
i: Integer;
grid:THackDBGrid;
begin
p := Mouse.CursorPos;
grid := THackDBGrid(Column.Grid);
p := grid.ScreenToClient(p);
col := grid.MouseCoord(p.X,p.Y);
i := grid.RawToDataColumn(col.X);
Label1.Caption := 'Column index: ' + IntToStr(i);
end;

Resources