Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Delphi XE and unbound TdbGrid 2

Status
Not open for further replies.

Kenbla

Programmer
Oct 11, 2006
68
SE
Hi there, I wonder if it is possible to use the TdbGrid component unbound (without a datasource)?
I want to use a grid in a separate form where the user can enter information on multiple lines and columns like in Excel for example. When the user is done and click the OK button the control goes back to the main/calling program where I perform some database actions using the information entered by the user.
It sounds pretty simple and straightforward, but I don't know how to do it!
Do I have to "fake" a datasource or how is it done?
I have created the form with the TdbGrid component. I have also added the columns for the grid (it looks nice) but I can't enter any information in the "data" grids below the columns, they are locked for some reason!
I would appreciate any help.
 
You need a TClientDataSet to accomplish this.

/Daddy

-----------------------------------------------------
What You See Is What You Get
Never underestimate tha powah of tha google!
 
Thanks Daddy, but how do I do that?
I have now added the TClientDataset component to the form but I don't know what to do with it!
Should I connect the TCliendDataset to the TdbGrid as DataSource?
How do I add records to the TClientDataset? I want to read information from a database and display the records in the grid where the user may modify it and when they are done I want to read the information in the grid and update the database accordingly.

Do you have any code example?
Regards,
Kenbla
 
I have now managed to create the TClientDataSet, it now contains a heading row and a few rows from a database. There are four "columns" in the dataset.
The next question is how to get the information in the clientdataset to the unbound TdbGrid?
Does anyone know?
Any help is greatly appreciated since I don't have a clue!
Regards,
Kenbla
 
Attach a datasource to your ClientDataSet, then drop a DBGrid on your form, set its datasource to the datasource you connected to the ClientDataSet.
 
Thanks Majlumbo, I have created the TClientDataset and I have a TdbGrid on the form but when I set the property "DataSource" on the Tdbgrid component to the name of my TClientDataset variable I get a message saying "Invalid property value". Do you have a code example which explains how to do this? It would be very appreciated.
 
Assuming your ClientDataSet is already set up, then

1) Drop a TDataSource (Data Access tab) on your form.

2) Set the DataSource's DataSet Property to your ClientDataSet (should be in the drop down in the object inspector)

3) Drop a TDBGrid on your form, Set it's DataSource property to DataSource1 (Also should be in the drop down in the object inspector)

4) You can (don't have to) double click on the DBGrid, and add the fields defined in your ClientDataSet, this allows you to change the Title's of each of the fields.

or in code (assuming you have the components on the form, i.e. not creating them dynamically)

DataSource1.DataSet := ClientDataSet1;
DBGrid1.DataSource := DataSource1;
 
Thanks again Majlumbo! Finally I got it to work thanks to you!
I can now display records from a database using the clientdataset. There is still one problem and that is how to update the values of these "cells", they are all locked.
Is it possible to enable/disable the cells individually?
I want to lock all columns in the first row (the headings) and the first column on all other rows the rest of the "cells" should be enabled so the user can enter information.
The enabled property in the dbGrid and Datasource are set to True but it doesn't help, I have also tried some other property setting at runtime but I don't get it to work properly.
Regards,
Kenbla
 
A information within a DBGrid should be editable, but of course there are things that can disable that. A few things to check..

1) Is the ClientDataSet's ReadOnly property true?
If So, make it false

2) Is the DBGrid's ReadOnly property true?
If So, make it false

3) Is the DBGrids.Options.dgEditing false (double click on Options within the object inspector to open it up)
If So make it true (If you can't make it true see #4)

4) Is the DBGrids.Options.dgRowSelect true(if true, it will automatically set dgEditing to false),
If So make it False

Also, I'm assuming you didn't insert code into the ClientDataSet's Before Edit or Before Insert that would cancel the action, that would obviously make it seem like you couldn't edit the fields in the DBGrid.
 
Thanks again Majlumbo!
It was the DBGrids.Options.dgEditing that was set to False, I have changed it now and my "cells" are now editable!
Do you know if it is possible to set certain cells to "protected" and some "editable"?
 
If you double clicked on your DBGrid and added each column you wanted to display on the grid, then simply click on the field and set its readonly property to true. That makes that column un-editable only within the dbgrid).

Another approach is to make the field un-editable from within the clientdataset. Doubleclick on the ClientDataSet, click on the field, set its read only property to true. (this makes it un-editable program wide).
 
Thanks for your help Majlumbo! You are my new Delphi hero!! Everything works just fine thanks to you!
Best regards,
Kenbla
 
star for you maljumbo!

-----------------------------------------------------
What You See Is What You Get
Never underestimate tha powah of tha google!
 
Just giving back... I learned a lot from the forum over the past few years.

Thanks for the kudos though, they are appreciated.
 
Hello again! I have an unbound grid that's working pretty well now! I can update individual cells and I can create new rows/records BUT I don't know how to delete rows/records that exist in the grid! I have looked for properties in the clientdataset as well as the dbgrid but I can't find anything that seems to do the job!
Does anyone know how it is done?
Regards,
Kenbla
 
The DBGrid is no more than a control to display the records from you clientdataset. If you want to delete a record from the grid, you need to delete it from the ClientDataSet.

With the record you want to delete selected, use:

ClientDataSet1.Delete;

to delete the record. You could code this into a delete button, popup menu item, or even the keydown event for the grid testing to see if the user hit the delete key

if Key = VK_DELETE then
...

If you don't actually want to delete the record, but don't want it displayed, then you could possibly use the filter/filtered properties of the ClientDataSet.
 
Thanks Majlumbo, I think I know how it's done in the code but I wonder how I should do it in the GUI! Is it possible to add a "delete icon" or something like that on each row or how would you do it?
 
In the past, I've had both a popup menu with a "delete" menu item (you need to add a popup menu to your form, double click it, add a "Delete" menu item, then add a method to the menu item, and coded the keydown event for the DBGrid to fire off if the key = VK_DELETE. Both items can point to the same code

in the keydown:

Code:
procedure TForm1.DBGrid1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
   if (Key = VK_DELETE) and (ClientDataSet1.RecordCount > 0) then
      DeleteCurrentRecord;
end;
in the delete menu item

For the popup menu, you wouldn't want to display the delete menu item if there are no records to delete, so you could add a OnPopUp method for your popup menu that checks and sets the visibility of the menu item accordingly.
Code:
procedure TForm1.PopupMenu1Popup(Sender: TObject);
begin
   Delete1.Visible := ClientDataSet1.RecordCount > 0;
   //assumes menu item is called Delete1..
end;
Then the menu click event would be:
Code:
procedure TForm1.Delete1Click(Sender: TObject);
begin
   DeleteCurrentRecord;
end;

Then add DeleteCurrentRecord as a private procedure to your form's declaration and define the procedure.
Code:
procedure TForm1.DeleteCurrentRecord;
begin
   if MessageDlg('Confirm Delete?', mtConfirmation, [mbYes, mbNo], 0) = mrYes then
      ClientDataSet1.Delete; 
end;

I haven't tested the above code...
 
Thanks again Majlumbo, I have added a popup menu to the form and when the user choose "Delete" from the popup menu the following code gets executed:
cdClientDataSet.DisableControls;
cdClientDataSet.Delete;
cdClientDataSet.EnableControls;

This removes the row from the clientdataset.

I think (hope) I got it all to work now!
Thanks a lot!
 
I'm glad you remembered to disable/enable controls, even though I didn't
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top