TcxGrid Auto posting if another row is focused? - delphi

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;

Related

FireMonkey FlowLayout isn't refreshing items based on visible property

How are you? Hope you doing fine.
My question: I have a FlowLayout with a lot of layouts inside it, and I need to hide a few based on a radio button selection, in design time it works fine I set the visible property to false and all the other layouts realign the right way, but when I do this at runtime it doesn't work, it keeps a white gap between the layout that has been hidden and the next one. When I do a resize manually (go to the form border and drag a little) it realigns and gets right, but if I select another radio the layout gets back and it override another layout so I need to resize manually again to realign. I tried to look at the source code of Resize but I got nothing relevant. What I tried: Repaint, Realign, InvalidateRect, RecalcAbsolute. Is there any way that I have to force the refresh of components?
procedure
TFrmApontamentoProducaoOrdemProducao.rbOrdensProducaoQuantidadeParcialClick(
Sender: TObject);
begin
if not lytQuantidadeParcial.Visible then
lytQuantidadeParcial.Visible := True;
// Tried to realign here
end;
procedure
TFrmApontamentoProducaoOrdemProducao.rbOrdensProducaoQuantidadeTotalClick(
Sender: TObject);
begin
if lytQuantidadeParcial.Visible then
lytQuantidadeParcial.Visible := False;
// Tried to realign here
end;
It's a simple code, but it's giving me a little problem. Thanks for the help, if you need more code or more details just let me know.
You must surround your code that makes changes to the layout of the TFlowLayout with a pair of FlowLayout1.BeginUpdate; and FlowLayout1.EndUpdate; To assure that the update counter stays in sync, you should also use a try..finally..end block.
For example
procedure TForm21.Button6Click(Sender: TObject);
begin
FlowLayout1.BeginUpdate;
try
Layout3.Visible := not Layout3.Visible;
finally
FlowLayout1.EndUpdate;
end;
end;
Using BeginUpdate cause access violation on a project when insert chars from tcp-ip comunication in real time on FlowLayout, the solution:
var
PodeAtualizarGrade:TCriticalSection;
// ...
FormCreate
PodeAtualizarGrade:=TCriticalSection.Create;
// ...
PodeAtualizarGrade.Enter;
(FlowLayout.AddObjects)
PodeAtualizarGrade.Leave;
Works fine on my project.

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;

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: TabStop problems of TRadioButton

When TRadioButton has TabStop=True, it's acting very strange.
If you will try to switch focus between many radio buttons on a form using Tab key, you would do it only 1 time per app session. The tabulation is one-way, never returning back to the first radio button. Also when the focus is moving across radio buttons, they becoming "checked" automatically.
Can this behavior be fixed without creating my own component?
I want standard radio buttons to
switch focus cyclically
prevent radio button from checking when the focus comes into it (I want my users to check them using Space key)
I understand that you're working with existing code, which is a real world constraint that's too often dismissed in these forums.
Sounds to me like checkboxes would suit you better. You can enforce the exclusivity normally expected of RadioButtons in the OnChecked event. That should solve your tabbing/focus and selection/deselection issues.
Checkboxes won't be checked automatically upon receiving focus, and your users can check/uncheck them with the space key.
You can put code in the OnEnter event to prevent the checkbox from selecting.
You'll need to store the previously selected RadioButton somehow though.
var
SelectedRadioButton: TRadioButton;
//event shared by all radiobuttons
procedure TForm1.RadioButton1Enter(Sender: TObject);
begin
if Sender <> SelectedRadioButton then begin
SelectedRadioButton.Checked:= true;
end;
end;
procedure TFrameOrder.RadioButton1Click(Sender: TObject);
begin
SelectedRadioButton:= (Sender as TRadioButton);
end;
procedure TFrameOrder.RadioButton1KeyPress(Sender: TObject; var Key: Char);
var
MyRadioButton: TRadioButton;
begin
MyRadioButton:= (Sender as TRadioButton);
if Key in [#32,#13] then begin
MyRadioButton.Checked:= true;
RadioButton1Click(MyRadioButton);
end; {if}
end;
It probably clearer to create a new TMyRadioButton component though because this will clutter up your regular code.
I have found an interesting article of Craig Stuntz about this problem. As I can see, I'll need to create my own control to solve it.
By default only one RadioButon has property TabStop = True;
All Radiobuttons are treated as one controll.
When radiobutton has focus you can switch beetween radiobutons using arrow up and down.
Now when user choose one option they can press tab to switch to another controll (without changing radio options).

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.

Resources