Link to home
Start Free TrialLog in
Avatar of ahalya
ahalyaFlag for Canada

asked on

Assigning a value to TDBEdit.text

I seem to get inconsistent behaviour when assigning a value to DBEdit components.  (DBEdit.Text := 'New Text')  Occasionally they show in display, mostly do not. And, they never seem to change the underlying database.

Any text typed by the user works fine.  The only way to make assignment in code work is to assign the value to underlying datafield. (i.e, DBEdit.Datasource.Dataset.FieldByName(DBEdit.FieldName).AsString := 'New Text' works fine. But, isn't that an overkill ?)

A look at the VCL shows that the assignment is executed via the private "SetText" method of TCustomMaskEdit component (which is the ancestor of TDBEdit).  Two questions:

1. Why didn't Borland/CodeGear/mbacardaro add an inherited SetText method to the TDBEdit component ?

2. Can one add SetText method to the TDBEdit component, which simply would set the underlying datafield and then call the inherited method ?  (presumably, VCL has be be tweaked to make the inherited method accessible).  Are there any known side effects to this?

Oh, by the way the TDBCoboBox is also a mess, when it comes to assignment via code :-)
Avatar of AndersonCarli
AndersonCarli

You shoud never assing value directly to Text property of a Dataware control.
As you said: Use the underling Field to update the Controls Text.

Instead using
DBEdit1.Text := 'Some Text'
use
DBedit1.Field.Value := 'Some Text'

You'll update the Contron AND the dataset;
Some points I'm sure you already know
1) If you do edit the text of a data-aware control, this will place the underlying dataset into Edit mode if it isn't already. (see the exception below) Unless you call post, it may not stick.
2) If your dataset is readonly (some Queries return readonly result-sets) then obviously it's not going to stick.
I know that doesn't really answer your question, but I think I ended up setting the value of the dataset rather than the data-aware control.
Oh and you should also look out for code that might move the dataset's cursor although usually that shouldn't be a problem. For example, you go and set the text of a data-aware control, it gets placed into Edit mode. You close the form and ultimately close the application. But you didn't call Post - so the value doesn't commit.
Another example: you edit the value of a data-aware control which places it into edit mode. Elswehere some code moves the cursor forward or back, as in MyDataSet.Next - some datasets might not call post automatically, but usually they do.
Avatar of ahalya

ASKER

My dataset is already in EditMode.

What I am trying to do is to format the user input to trim spaces, change multiple spaces to a single space etc.

The "beef" I have with the current design is that they should have made the text property readonly, or should have properly handled assignments to it by updating the underlying datafield.

A derived TMyDBEDit as shown below should do the trick. Isn't it ?

type
  TMyDBEdit = class(TDBEdit)
  protected
    function GetText:TMaskedText;
    procedure SetText(const Value: TMaskedText);
  public
    property text:TMaskedText read GetText write SetText;
  end;
 
implementation
 
function GetText:TMaskedText;
 
begin;
  result := inherited text;
end;
 
procedure SetText(const Value: TMaskedText);
 
begin;
  DataSource.DataSet.FieldBtName(DataField).AsString := Value;
  inherited text := Value;
end;

Open in new window

Avatar of kretzschmar
???

usual the underlying tfield has the events you want
to use and where you can manipulate it in your manner you need

you are just looking on the wrong place

just assign the events on the desired tfield,
simpelsed using persistent fields
(just ask, if unknown, how to create persistent fields)

meikl ;-)
Avatar of ahalya

ASKER

Meikl:

I know the basics of working with the underlying dataset.  But, I do not know much about the 'persistent fields'.  Can you provide a sample, and explain please.

Also, my difficulty here is that DBEdit.Text is NOT a read only property.  So, what was the intent of Borland, when they allowed TDBEdit.text  to be writable ? (There is a work around using underlying datasets, but isn't this bad design ?)

Thanks.
Okay, with fields, each Tfield has a field type, such as integer, string etc etc as well as a kind : data, calculated, etc.
Every time a dataset is opened or a query is fetched, the field information is fetched automatically.
With persistent fields however, you store this information in the dataset component itself (I think it gets stored in the dfm). All you need to do is double-click on the dataset at design time. If the dataset is open (recommended at this point in the procedure) you will be able to "add" all the existing fields as persistent fields.
With all the persistent fields in a dataset, you'll notice in the object inspector the fieldtype: data, calculated, lookup etc. So it would be possible to, for example, create a new persistent field, and make it calculated. Then on your dataset's onCalculate property you can then do the calculations of the field, for example
MyDataset.FieldByname('MyCalculatedTaxField').value :=
  MyDataset.FieldByName('SaleAmount').asFloat * 0.14; //14% tax rate.
I've used persistent fields for all kinds of reasons. For example you can set the display formatting of a persistent field. Or perhaps in your database a field is of type Float but in your application you want it to display as a currency. All you do is make it a persistent field and set it as a currency in the object inspector. Then it will kindly display the system's currency symbol whenever it is displayed.

The same principals of persistent fields apply to DBGrid fields. You can double-click ona DBGrid and add fields as you go (again, make sure the dataset is open for this step). One time I used a DBGrid persistent field to create a "separator" column. This was a field with no title, a width of 5, and a dark colour.
..hope that explains persistent fields.
Avatar of ahalya

ASKER

Thanks rkWoolf.

I have been using those but didn't realize they are called the 'Persistent Fields'.  Thanks for clarifying it.  

Going back to the original question, can anyone explain what was the purpose behind leaving DBEdit.Text as a writable field ?  

(Is there a reason, or just bad design on the part of Borland/Inprise/CodeGear/Embarcardaro ?).

ASKER CERTIFIED SOLUTION
Avatar of rfwoolf
rfwoolf
Flag of South Africa image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of ahalya

ASKER

Thanks for the suggestion