I would like to change DBgrid row value with outside data, how to achieve that?
For example i would like to add Tedit value into dbgrid selected row column(for example 5) via button click.
Also, i would like to add value from 1 dbgrid to another dbgrid.(Add to an existing number, not replace).
Suppose you have a dataset connected to db-aware controls like TDBEdit and TDBGrid via a TDataSource. Delphi's db-aware controls are basically the default ones which come with Delphi and are displayed on the Data controls tab of its Component Palette plus any 3rd-party ones that you install. The reason they are called db-aware is because they are written so that the values they display are automatically derived from the related fields of the dataset.
Also suppose that the dataset is called Table1 and has a CustomerName field that you want to change. The simplest code which will achieve that is something like:
Table1.Edit; // put table one into dsEdit state so that field values can be changes
Table1.FieldByName('CustomerName').AsString := 'Jones';
Table1.Post; // save the change(s) to Table1
More optimal code might be
Table1.Edit;
try
Table1.DisableControls; // this prevents the db-aware controls updating on-screen while the changes are made
Table1.FieldByName('CustomerName').AsString := 'Jones';
Table1.FieldByName('CustomeCountry').AsString := 'DE#;
finally
Table1.Post;
Table1.EnableControls; // Eable screen updating od the db-aware controls again
end;
That would update the values displayed in DBEdit controls linked to the CustomerName and CustomerCountry fields and in the CustomerName and CustomerCountry cells of the current (i.e. highlighted) row in the DBGrid, because the current row in the DBGrid always tracks the current row in the connected dataset.
If you really do want to update a given column from a TEdit's text you could do that like this:
Table1.Edit;
DBGrid1.Columns[5].Field.AsString := Edit1.Text;
Table1.Post;
When saving a form with a TDBGrid having a column with Visible = false, the column's Width property is not saved, and the original value of the Width property is lost.
The context is a TColumn in a standard VCL TDBGrid control on a form (Delphi 10.1 Berlin). If the Visible property of the column is set to false in the object inspector, the Width property immediately goes to -1. Setting Visible back to true, restores the previous value of Width.
However, if the form is saved while the column's Visible property is false, and the form is closed and reopened, then the same column's Visible property is set to true again, the Width always comes back as 163839. This of course hides any other columns to the right, and messes up scrolling, which rightly confuses non-technical users.
I suspect it is a VCL bug, since the property getter for the TColumn.Width property (in unit Vcl.DBGrids) is as follows:
unit Vcl.DBGrids;
...
function TColumn.GetWidth: Integer;
begin
if not Showing then // depends on Visible property
Result := -1 // obviously streamed to .DFM
else if cvWidth in FAssignedValues then
Result := FWidth
else
Result := DefaultWidth;
end;
Is this a VCL bug, or am I using it wrong?
PS: does this have anything to do with TColumn.AssignedValues? Or is the built-in Delphi DBGrid just flawed.
Edit: My app allows the user to resize, reorder and show/hide columns in a main results grid at run-time, but also to restore back to defaults. I'm using the grid at design-time as the "master" when restoring defaults, i.e. default column widths and order, and also which columns are visible by default. But losing the column Width for columns hidden by default is messing with that.
I am facing a strange problem when removing the horizontal scrollbar from TListView.
procedure TForm1.listDataResize(Sender: TObject);
begin
ShowScrollBar(listData.Handle, SB_HORZ, False);
end;
When using down or up arrow keys, then Column header Second and beyond is erased, when i resize the column manually then it is displayed back. When i remove the code from listDataResize then this problem no more occurs.
I just want to remove the horizontal scroll-bar from appearing in the ListView. As above code is working fine, the only thing bothering me is why second and beyond column headers are erased.
I don't know why it was happening, I deleted the current form holding TListView and created a new Form not touched any property of the form except Caption of the form and dropped the TListView once again.
ListView.RePaint;
ListView.Refresh;
Now it is no-more erasing the column header. I have not touched any property like double buffering etc. Working good.
I can't seem to get the fixed row Titles in a DBGrid to align right justified when using a FDMemtable. Whenever I set the Field alignment to taRightJustify it right justifies the data cells perfectly. However, the DBGrid titles are always left justified.
What's even more frustrating is I can set the corresponding DBGrid column title alignment to taRightJustify and it appears perfectly fine in the IDE. But when I run the program the column title shows as left justified.
Has anyone found a way to make DBGrid column titles stay right justified when using a FDMemtable?
BTW, this also happens with taCenter. The data cells align centered but the titles stay left justified.
PEBKAC
The issue was of my own making. I did not invoke the DBGrid Columns Editor and add all the fields. Instead, I was using the "Structure" pane and getting to the DBGrid columns that way. Although the Structure pane allowed me to modify the column titles this was only temporary and did not persist when the program was run.
I can't reproduce the issue using a TFDMemTable either.
I dropped a TFDMemTable, TDataSource, and TDBGrid on a new VCL application's main form, connected them as usual (the grid's datasource set to DataSource1, the datasource's DataSet set to FDMemTable1), and then added the below code to the form's OnCreate event:
procedure TForm3.FormCreate(Sender: TObject);
begin
FDMemTable1.FieldDefs.Add('ID', ftInteger, 0, True);
FDMemTable1.FieldDefs.Add('LastName', ftString, 20);
FDMemTable1.FieldDefs.Add('FirstName', ftString, 20);
FDMemTable1.FieldDefs.Add('Salary', ftCurrency);
FDMemTable1.CreateDataSet;
FDMemTable1.Active := True;
FDMemTable1.AppendRecord([1, 'Smith', 'John', 30000]);
FDMemTable1.AppendRecord([2, 'Jones', 'Jane', 40000]);
FDMemTable1.AppendRecord([3, 'Doe', 'David', 2500]);
DBGrid1.Columns[3].Alignment := TAlignment.taRightJustify;
DBGrid1.Columns[3].Title.Alignment := TAlignment.taRightJustify;
end;
It also works correctly if I set everything up at designtime. Repeat the same setup steps I used above, but instead of using the code, use the following steps:
Select FDMemTable1 in the Object Inspector. At the bottom of the OI, click the LoadFromFile link, and navigate to the BDS Samples data folder (by default, in C:\Users\Public\Public Documents\Embarcadero\Studio\17.0\Samples\Data) and select animals.fds. (No specific reason for choosing that one, except it has a numeric field we can use for testing.)
Right-click on the DBGrid, and choose Columns Editor, or click the ellipsis button on the DBGrid.Columns property in the Object Inspector. Right-click in the Columns Editor and choose Add all fields.
Select either the Size or Weight column, expand it's Title property, and set Alignment to taRightJustify.
Run the application. The column you modified in step #3 above has a right-aligned title. (Here I used the Size column.)
The code below works for me in Seattle. I'm using a TClientDataSet rather than a TFDMemTable, but I can't see that that would make any difference.
If you have persistent columns defined on your DBGrid, you can also set a column's title alignment via the Object Inspector - use it to select the column, then expand its Title node and you can set the title alignment there.
procedure TForm1.CDS1AfterOpen(DataSet: TDataSet);
var
i : Integer;
begin
for i := 0 to DBGrid1.Columns.Count - 1 do
DBGrid1.Columns[i].Title.Alignment := taRightJustify;
end;
Btw, if you think you're setting the alignment in the OI but it's getting ignored, see if you can find out why, as follows:
Make sure your form is saved, then right-click on it and select View as text. Then, in the IDE editor window, you can see whether the Alignment property is saved as you've specified in the OI. Use the editor context menu to return to viewing the form as a form.
Add an override of the form's Loaded method as I've described in a comment. With a breakpoint on the inherited in Loadeds body, you can inspect the Alignment value before and after inherited is called.
Why am I suggesting looking into Loaded? Well, it is called after a form is streamed in from the DFM and is the routine where the run-time system finishes setting up the form. Sometimes, admittedly very rarely, another component (usually a 3rd-party one) misbehaves and causes strange behaviour of the properties of other compononents.
I have a VirtualTreeView which has some columns initially hidden (coVisible is not present).
After enabling them (adding coVisible to the column Options) a strange thing happens - column appears but overlaps with previous column. I can fix the problem by changing width to 1 pixel smaller, then back to original width of the column which forces some repaint which then displays column correctly.
Is there something I need to do additionally except adding coVisible to make the columns repaint properly?
Use:
VTV.Header.Columns.BeginUpdate;
try
// Enable or Disable columns...
finally
VTV.Header.Columns.EndUpdate;
end;
This should keep the Header.Columns in sync.