Modify DBGrid cell content before it is displayed
I want to modify the content of a particular cell in dbgrid control when the database 开发者_JAVA技巧is loaded. For example, lets say I don't want any field of database to be displayed in dbgrid if it is equal to "forbidden". Is there any way that I can do that?
Going to your original question:
Use the OnGetText
event of the field to provide a different value from what is stored on the database for presentation purposes.
The DisplayText
boolean parameter will be True if the value is required to be presented to the user and will be False if the value is required for other purposes.
procedure TForm1.SQLQuery1Field1GetText(Sender: TField;
var Text: string; DisplayText: Boolean);
begin
if (Sender.AsString = 'forbidden') and (DisplayText)
and (PrivilegeLevel(CurrentUser) < 10) then
Text := '********'
else
Text := Sender.AsString;
end;
you can use the DataSetNotifyEvent Afteropen
DBGrid.Datasource.Dataset.Afteropen :=
and you can hide fields with:
if Condition then DBGrid.columns[x].visible := false
alternative you can check the condition on the OnDrawColumnCell event in order to overrite / delete some content in a specific cell
Using the DataSet events to synchronize UI is not a good practice. You can rely on DataSource events to do that, separating UI Logic from business logic.
As the state of the DataSet will change from dsInactive to dsBrowse, you can rely on the DataSource OnState change to make anything UI-related upon the data is loaded from database.
You can rely on a Auxiliar field to track previous state to avoid the code executing more than needed.
for example (untested code)
procedure TForm1.DataSource1StateChange(Sender: TObject);
begin
if (DataSource1.State = dsBrowse) and (not FUIStateInSync) then
begin
//dataset is open, change UI accordingly
DBGrid1.Columns[0].Visible := SomeCondition();
//this will prevent the code to be executed again
//as state comes to dsBrowse after posting changes, etc.
FUIStateInSync := True;
end
else if (DataSource1.State = dsInactive) then
FUIStateInSync := False; //to let it happen again when opened.
end;
I publish this even when you have an accepted answer, because O.D. suggestion is just what you shall avoid.
Hookup OnAfterOpen event on dataset. Get the hidden fields and set its Visible property to False and your dbgrid will not display them
Cheers
I would modify the query that provides the data to the grid so as not to include rows (tuples) which have the 'forbidden' string. This seems much easier than trying hard not to display data after it has already been retrieved from the database.
I think that the best way would be not to SELECT the fields WHERE SOME_VALUE="forbidden" FROM the DATABASE_TABLE
精彩评论