Delphi Programming Guide
Delphi Programmer 

Menu  Table of contents

Part I - Foundations
  Chapter 1 – Delphi 7 and Its IDE
  Chapter 2 – The Delphi Programming Language
  Chapter 3 – The Run-Time Library
  Chapter 4 – Core Library classes
  Chapter 5 – Visual Controls
  Chapter 6 – Building the User Interface
  Chapter 7 – Working with Forms
Part II - Delphi Object-Oriented Architectures
  Chapter 8 – The Architecture of Delphi Applications
  Chapter 9 – Writing Delphi Components
  Chapter 10 – Libraries and Packages
  Chapter 11 – Modeling and OOP Programming (with ModelMaker)
  Chapter 12 – From COM to COM+
Part III - Delphi Database-Oriented Architectures
  Chapter 13 – Delphi's Database Architecture
  Chapter 14 – Client/Server with dbExpress
  Chapter 15 – Working with ADO
  Chapter 16 – Multitier DataSnap Applications
  Chapter 17 – Writing Database Components
  Chapter 18 – Reporting with Rave
Part IV - Delphi, the Internet, and a .NET Preview
  Chapter 19 – Internet Programming: Sockets and Indy
  Chapter 20 – Web Programming with WebBroker and WebSnap
  Chapter 21 – Web Programming with IntraWeb
  Chapter 22 – Using XML Technologies
  Chapter 23 – Web Services and SOAP
  Chapter 24 – The Microsoft .NET Architecture from the Delphi Perspective
  Chapter 25 – Delphi for .NET Preview: The Language and the RTL
  Appendix A – Extra Delphi Tools by the Author
  Appendix B – Extra Delphi Tools from Other Sources
  Appendix C – Free Companion Books on Delphi
  List of Figures    
  List of tables    
  List of Listings    
  List of Sidebars  

Previous Section Next Section

Using Data-Aware Controls

Once you set up the proper data-access components, you can build a user interface to let a user view the data and eventually edit it. Delphi provides many components that resemble the usual controls but are data-aware. For example, the DBEdit component is similar to the Edit component, and the DBCheckBox component corresponds to the CheckBox component. You can find all these components in the Data Controls page of the Delphi Component Palette.

All these components are connected to a data source using the corresponding property, DataSource. Some of them relate to the entire dataset, such as the DBGrid and DBNavigator components, and the others refer to a specific field of the data source, as indicated by the DataField property. Once you select the DataSource property, the DataField property editor will contain a list of available values.

Notice that all the data-aware components are unrelated to the data-access technology, provided the data-access component inherits from TDataSet. Thus your investment in the user interface is preserved when you change the data-access technology. However, some of the lookup components and extended use of the DBGrid (displaying a lot of data) make sense only when you're working with local data and should generally be avoided in a client/server situation, as you'll see in Chapter 14.

Data in a Grid

The DBGrid is a grid capable of displaying a whole table at once. It allows scrolling and navigation, and you can edit the grid's contents. It is an extension of the other Delphi grid controls.

You can customize the DBGrid by setting its Options property's various flags and modifying its Columns collection. The grid allows a user to navigate the data using the scrollbars and perform all the major actions. A user can edit the data directly, insert a new record in a given position by pressing the Insert key, append a new record at the end by going to the last record and pressing the Down arrow key, and delete the current record by pressing Ctrl+Del.

The Columns property is a collection from which you can choose the table fields you want to see in the grid and set column and title properties (color, font, width, alignment, caption, and so on) for each field. Some of the more advanced properties, such as ButtonStyle and DropDownRows, can be used to provide custom editors for a grid's cells or a drop-down list of values (indicated in the column's PickList property).

DBNavigator and Dataset Actions

DBNavigator is a collection of buttons used to navigate and perform actions on the database. You can disable some of the DBNavigator control's buttons by removing some of the elements of the VisibleButtons set property.

The buttons perform basic actions on the connected dataset, so you can easily replace them with your own toolbar, particularly if you use an ActionList component with the predefined database actions provided by Delphi. In this case, you get all the standard behaviors, but you'll also see the various buttons enabled only when their action is legitimate. The advantages of using the actions is that you can display the buttons in the layout you prefer, intermix them with other buttons of the application, and use multiple client controls, including main and popup menus.


If you use the standard actions, you can avoid connecting them to a specific DataSource component, and the actions will be applied to the dataset connected to the visual control that currently has the input focus. This way, a single toolbar can be used for multiple datasets displayed by a form, which can be very confusing to the user if not considered carefully.

Text-Based Data-Aware Controls

There are multiple text-oriented components:

DBText  Displays the contents of a field that cannot be modified by the user. It is a data-aware Label graphical control. It can be very useful, but users might confuse this control with the plain labels that indicate the content of each field-based control.

DBEdit  Lets the user edit a field (change the current value) using an Edit control. At times, you might want to disable editing and use a DBEdit as if it were a DBText, but highlight the fact that this is data coming from the database.

DBMemo  Lets the user see and modify a large text field, eventually stored in a memo or BLOB (binary large object) field. It resembles the Memo component and has full editing capabilities, but all the text is rendered in a single font.

List-Based Data-Aware Controls

To let a user choose a value in a predefined list (which reduces input errors), you can use many different components. DBListBox, DBComboBox, and DBRadioGroup are similar, providing a list of strings in the Items property, but they do have some differences:

DBListBox  Allows selection of predefined items (closed selection), but not text input, and can be used to list many elements. Generally it's best to show only about six or seven items to avoid using up too much space on the screen.

DBComboBox  Can be used both for closed selection and for user input. The csDropDown style of the DBComboBox allows a user to enter a new value, in addition to selecting one of the available values. The component also uses a smaller area on the form because the drop-down list is usually displayed only on request.

DBRadioGroup  Presents radio buttons (which permit only one selection), allows only closed selection, and should be used only for a limited number of alternatives. A nice feature of this component is that the values displayed can be those you want to insert in the database, but you can also choose to provide mapping. The values of the user interface (descriptive strings stored in the Items property) will map to corresponding values stored in the database (numeric or character-based codes listed in the Values property). For example, you can map numeric codes indicating departments to a few descriptive strings:

object DBRadioGroup1: TDBRadioGroup
  Caption = 'Department'
  DataField = 'Department'
  DataSource = DataSource1
  Items.Strings = (
  Values.Strings = (

The DBCheckBox component is slightly different; it is used to show and toggle an option, corresponding to a Boolean field. It is a limited list because it has only two possible values plus the undetermined state for fields with null values. You can determine which are the values to send back to the database by setting the ValueChecked and ValueUnchecked properties of this component.

The DbAware Example

The DbAware example highlights the usage of a DBRadioGroup control with the settings discussed in the previous section and a DBCheckBox control. This example is not much more complex than earlier ones, but it has a form with field-oriented data-aware controls, instead of a grid encompassing them all. You can see the example's form at design time in Figure 13.3.

Click To expand
Figure 13.3: The data-aware controls of the DbAware example at design time in Delphi

As in the MyBase2 program, the application defines its own table structure, using the FieldDefs collection property of the ClientDataSet. Table 13.1 provides a short summary of the fields defined.

Table 13.1: The Dataset Fields in the DbAware Example






















The program has some code to fill in the table with random values. This code is tedious and not too complex, so I won't discuss the details here, but you can look at the DbAware source code if you are interested.

Using Lookup Controls

If the list of values is extracted from another dataset, then instead of the DBListBox and DBComboBox controls you should use the specific DBLookupListBox or DBLookupComboBox component. These components are used every time you want to select for a field a value that corresponds to a record of another dataset (and not to choose a different record to display!).

For example, if you build a standard form for taking orders, the orders dataset will generally have a field hosting a number indicating the customer who made the order. Working directly with the customer number is not the most natural way; most users will prefer to work with customer names. However, in the database, the customers' names are stored in a different table, to avoid duplicating the customer data for each order by the same customer. To get around such a situation, with local databases or small lookup tables, you can use a DBLookupComboBox control. (This technique doesn't port well to client/server architecture with large lookup tables, as discussed in the next chapter.)

The DBLookupComboBox component can be connected to two data sources at the same time: one source containing the data and a second containing the display data. I built a standard form using the orders.cds file from the Delphi sample data folder; the form includes several DBEdit controls.

You should remove the standard DBEdit component connected to the customer number and replace it with a DBLookupComboBox component (and a DBText component, to fully understand what is going on). The lookup component (and the DBText) is connected to the DataSource for the order and to the CustNo field. To let the lookup component show the information extracted from another file (customer.cds) you need to add another ClientDataSet component referring to the file, along with a new data source.

For the program to work, you need to set several properties of the DBLookupComboBox1 component. Here is a list of the relevant values:

object DBLookupComboBox1: TDBLookupComboBox
  DataField = 'CustNo'
  DataSource = DataSourceOrders
  KeyField = 'CustNo'
  ListField = 'Company;CustNo'
  ListSource = DataSourceCustomer
  DropDownWidth = 300

The first two properties determine the main connection, as usual. The next four properties determine the field used for the join (KeyField), the information to display (ListField), and the secondary source (ListSource). In addition to entering the name of a single field, you can provide multiple fields, as I did in the example. Only the first field is displayed as combo box text, but if you set a large value for the DropDownWidth property, the combo box's drop-down list will include multiple columns of data. You can see this output in Figure 13.4.

Click To expand
Figure 13.4:  The output of the CustLookup example, with the DBLookupCombo-Box showing multiple fields in its drop-down list

If you set the IndexFieldNames property of the ClientDataSet containing the orders data to the Company field, the drop-down list will show the companies in alphabetical order instead of customer-number order. I did this in the example.

Graphical Data-Aware Controls

Delphi includes a graphical data-aware control: DBImage. It is an extension of an Image component that shows a picture stored in a BLOB field, provided the database uses a graphic format that the Image component supports, such as BMP or JPEG (if you add the JPEG unit to your uses clause).

Once you have a table that includes a BLOB storing an image with a compatible graphic format, hooking it to the component is trivial. If, instead, the graphic format requires a custom transformation in order to be displayed, it might be easier to use a standard non-data-aware Image component and write code so the image is updated each time the current record changes. Before I can discuss this subject, however, you need to know more about the TDataSet class and the dataset field classes.

Previous Section Next Section



Delphi Sources

Copyright © 2004-2024 "Delphi Sources" by BrokenByte Software. Delphi Programming Guide
ร๐๓๏๏เ ยส๎ํ๒เ๊๒ๅ   Facebook   ั๑๛๋๊เ ํเ Twitter