亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

多層數據庫開發十二:使用數據控件

2019-11-18 18:10:55
字體:
來源:轉載
供稿:網友
 第十二章 使用數據控件
  在數據庫應用程序中,數據控件是經常要用到的。與前面介紹的數據集構件如TTable、TQuery、TStoredPRoc、TClientDataSet不同的是,數據控件都是可視的。也就是說,如果修改了這些構件的屬性,能在窗體上馬上反映出來。如果這些構件的Enabled屬性設為True并且數據集的Active屬性也設為True,在設計期就可以看到數據。
12.1 Delphi 4中有哪些數據控件
  在Delphi 4的IDE中,數據控件都位于構件選項板的“Data Controls”頁上。下面簡單介紹這些數據控件:
.TDBGrid以行和列組成的柵格顯示數據。
.TDBNavigator用于對整個數據庫的記錄進行導航,如向前翻一個記錄、向后翻一個記錄、翻到第一個記錄、翻到最后一個記錄等。
.TDBText把字段的內容作為標簽顯示。
.TDBEdit以編輯框的形式顯示一個字段的內容。
.TDBMemo以多行文本編輯器的形式顯示備注字段的內容。
.TDBImage用于顯示數據庫中的圖像字段。
.TDBListBox以列表框的形式顯示數據。
.TDBComboBox以組合框的形式顯示數據。
.TDBCheckBox以復選框的形式顯示數據。
.TDBRadioGroup以單選框分組框的形式顯示數據。
.TDBLookupListBox以列表框的形式顯示這個表的Lookup表的數據。
.TDBLookupComboBox以組合框的形式顯示這個表的Lookup表的數據。
.TDBRichEdit以RTF格式顯示備注字段的內容。
.TDBCtrlGrid與TDBGrid相似,但每一個單元都可以分別設置屬性。
.TDBChart以圖表的形式顯示數據庫的數據,用法與TChart相似。
  上述數據控件在設計期具有數據感知的特點。如果正確設置了DataSource屬性指定了一個數據源,馬上就能看到數據,而不需要編譯和運行程序。
12.2 數據控件的基本用法
  這一節介紹數據控件的基本用法,包括怎樣指定一個數據源、怎樣編輯和更新數據、怎樣禁止和允許數據刷新。
12.2.1 指定一個數據源
  數據控件必須通過TDataSource構件連接數據集。TDataSource構件扮演的角色實際上就是數據控件與數據集之間的橋梁。
  首先,把一個數據集構件放到窗體或數據模塊上,設置它的DatabaseName屬性指定要訪問的數據庫,設置它的TableName屬性指定要訪問的表。
  接著,把一個TDataSource構件放到窗體或數據模塊上,設置它的DataSet屬性指定數據集。
  然后,把一個數據控件放到窗體上,設置它的DataSource屬性指定TDataSource構件,而這個TDataSource構件的DataSet屬性已經指定了一個數據集。
  最后,設置數據控件的DataField屬性指定要顯示的字段。不過,對于TDBGrid、TDBCtrlGrid和TDBNavigator構件來說,不需要設置DataField屬性,因為這幾個控件是以整個數據集為工作內容的。
12.2.2 編輯和更新數據
  除了TDBNavigator構件外,其他數據控件都是用來顯示和編輯數據的。這里要介紹怎樣編輯數據。
  要使用戶能編輯數據,數據集必須進入dsEdit狀態。如果TDataSource的AutoEdit屬性設為False,用戶不能直接編輯數據,除非程序調用Edit函數。
  要使用戶能夠在數據控件中修改數據,必須把數據控件的ReadOnly屬性設為False。如果ReadOnly屬性設為True,數據控件中顯示的數據就是只讀的。
  一般情況下,TDataSource構件的Enabled屬性設為True。如果這個屬性設為False,數據控件就無法顯示數據,更不能修改數據。
  如果數據集構件的ReadOnly屬性設為True,數據集就是只讀的,用戶在數據控件中所作的修改不能寫到數據集中。
  除了TDBGrid構件外,當用戶修改了一個字段的值,還需要把輸入焦點移走,新的數據才寫到數據集中。在移走輸入焦點之前,用戶隨時可以按ESC鍵取消修改。
  在TDBGrid構件建立的柵格中,當用戶修改了一個字段的值,還需要把輸入焦點移到另一條記錄上,新的數據才寫到數據集中。
12.2.3 禁止和允許數據刷新
  當程序正在遍歷整個數據集或者搜索一個特定的記錄時,應當暫時禁止數據控件刷新數據,這樣能加快遍歷或搜索的速度,防止屏幕總是在閃爍。
  調用數據集的DisableControls可以暫時禁止連接這個數據集的數據控件刷新數據。DisableControls函數通常在循環操作前調用。等循環結束后,程序應當立即調用數據集構件的EnableControls函數重新允許刷新數據。
  為了確保最后總是能恢復刷新,建議采用Try...Finally結構。這樣,即使在循環中出現異常,也可以保證總能調用EnableControls。
  下面的代碼演示了怎樣調用DisableControls和EnableControls函數:
CustTable.DisableControls;
Try
  CustTable.First;
  While not CustTable.EOF Do
  Begin
   ...
   CustTable.Next;
  End;
Finally
  CustTable.EnableControls;
End;
12.2.4 手動刷新數據
  調用數據集的Refresh可以讀取數據集中最新的數據并刷新數據控件,這個功能在多用戶環境尤其有用,因為其他用戶有可能已改變了數據集中的數據。
  有時候,調用Refresh可能會導致意想不到的結果。例如,如果另一個用戶已經刪除了一條記錄,調用Refresh后,這條記錄將從數據控件中消失。
12.3 顯示單個字段的數據控件
  有的數據控件以數據庫的一個或幾個字段作為工作內容,如TDBText和TDBEdit,而有的數據控件以整個數據集為工作內容,如TDBGrid和TDBNavigator。
  顯示單個字段的數據控件往往是從一個標準的Windows控件演化而來的,例如,TDBEdit構件就可以認為是TEdit的數據感知版本。
  圖12.1 用TDBText構件把數據作為標簽顯示
12.3.1 把數據作為標簽顯示
  TDBText構件是一個只讀的數據控件,它非常類似于TLabel構件和TStaticText構件。TDBText構件能夠把數據作為標簽顯示,用來標注其他控件。例如,可以用一個TDBText構件在魚的圖片下顯示魚的名稱(Common_Name字段),如圖12.1所示。
  TDBText構件需要指定一個字段。當用戶使用導航器或其他手段瀏覽記錄時,TDBText構件顯示的數據將自動變化,因為TDBText構件總是顯示當前記錄的數據。例如,在圖12.1中,當用戶用鼠標單擊柵格的滾桿兩端的箭頭時,魚的圖片將自動變化,魚的名稱也相應改變,這一切都不需要編程。
  TDBText構件的AutoSize屬性一般要設為True,這是因為字段的內容長度可能是不同的。如果AutoSize屬性設為False,有些較長的內容可能會被截斷。
12.3.2 顯示和編輯數據
  TDBText構件只能顯示數據,不能編輯數據。要既能顯示數據,又能編輯數據,就要用到TDBEdit構件。TDBEdit可以認為是TEdit的數據感知(Data-Aware)版本。
  例如,有一個TDataSource構件叫Customerssource,它的DataSet屬性指向一個TTable構件叫CustomersTable。把一個TDBEdit構件放在窗體上,其DataSource屬性設為CustomersSource,把它的DataField屬性設為CustNo。這個TDBEdit構件馬上就能顯示CustNo字段的值。用戶可以在編輯框中鍵入新的值。
12.3.3 顯示和編輯多行文本
  TDBMemo構件是TMemo構件的數據感知版本,可以顯示dBASE和Paradox數據庫中備注字段的內容。
  與TDBEdit不同的是,TDBMemo能夠以多行的形式顯示文本,同時也允許用戶鍵入多行文本。
  默認情況下,TDBMemo允許用戶修改它顯示的文本。如果不想讓用戶修改文本,只要把ReadOnly屬性設為True即可。要允許用戶在文本中插入一個制表符,應當把WantTabs屬性設為True,否則,當用戶按下Tab鍵,將把輸入焦點移走,而不是插入制表符。
  要限制用戶最多可輸入的字符數,可以設置MaxLength屬性。如果這個屬性設為0,表示沒有限制。
  此外,ScrollBars屬性可以設置要不要加上滾動欄,WordWrap屬性可以設置是否允許自動繞回,Alignment屬性可以設置文本的對齊方式。
  在運行期,您可以調用CutToClipboard和CopyToClipboard函數把選擇的文本剪切和復制到剪貼板中,調用PasteFromClipboard能夠粘貼剪貼板中的文本。如果AutoDisplay屬性設為True,當DataField屬性所指定的字段的內容改變了時,TDBMemo構件會自動刷新。如果AutoDisplay屬性設為False,TDBMemo 構件上只顯示字段名,用戶必須雙擊這個構件或程序調用LoadMemo才能刷新數據。
12.3.4 以RTF格式顯示文本
  TDBRichEdit構件可以認為是TRichEdit構件的數據感知版本,用于以RTF格式顯示BLOB字段中的格式化文本。它的用法類似于TDBMemo構件,也能顯示多行文本。
  注意:盡管TDBRichEdit構件能夠顯示RTF格式的文本,并且提供了很強的編輯功能,但是,它本身并沒有提供用戶界面,應用程序必須設計出相應的用戶界面,才能把TDBRichEdit 構件強大的功能發揮出來。
  默認情況下,TDBRichEdit構件允許用戶鍵入新的文本。如果不想讓用戶修改文本,可以把ReadOnly屬性設為True。
  要允許用戶在文本中插入一個制表符,應當把WantTabs屬性設為True,否則,當用戶按下Tab鍵,將把輸入焦點移走,而不是插入制表符。
  要限制用戶最多可輸入的字符數,可以設置MaxLength屬性。如果這個屬性設為0,表示沒有限制。
  如果AutoDisplay屬性設為True,當DataField屬性所指定的字段的內容改變了時,TDBRichEdit構件會自動刷新。如果AutoDisplay屬性設為False,TDBRichEdit構件上只顯示字段名,用戶必須雙擊這個構件或程序調用LoadMemo函數才能刷新數據。
12.3.5 顯示和編輯圖像
  TDBImage構件可以認為是TImage構件的數據感知版本,它可以顯示BLOB字段的內容。TDBImage構件從數據集中檢索了圖像后,在本地以DIB格式建立一個副本。
  可以調用CutToClipboard或CopyToClipboard函數把圖像剪切或復制到剪貼板中,調用 PasteFromClipboard可以從剪貼板中粘貼圖像。
  如果Stretch屬性設為True,圖像將自動縮放,以適應TDBImage構件的大小,這樣就可能造成圖像變形。如果AutoDisplay屬性設為True,當DataField屬性所指定的字段的內容改變了時,TDBImage構件會自動刷新。如果這個屬性設為False,TDBImage構件上只顯示字段名,用戶必須雙擊這個構件才能刷新數據,當然也可以調用LoadPicture來刷新數據。
12.4 用列表框和組合框顯示和編輯數據
  有4個特殊的數據控件可以用列表框和組合框顯示和編輯數據,它們可以認為是標準的列表框和組合框的數據感知版本。下面簡單介紹這4個數據控件:
.TDBListBox用列表框顯示一組數據,讓用戶從中選擇一個值。
.TDBComboBox用組合框顯示一組數據,讓用戶從中選擇一個值。
.TDBLookupListBox用列表框顯示另一個數據集中的一組數據,讓用戶從中選擇一個值。
.TDBLookupComboBox用組合框顯示另一個數據集中的一組數據,讓用戶從中選擇一個值。
12.4.1 TDBListBox
  TDBListBox構件能夠用列表框顯示一組數據,用戶可以從中選擇一個數據。當用戶瀏覽記錄時,程序將自動在列表框中搜索與字段的值匹配的項,如果找到就選擇這一項,如圖12.2所示。
  在列表框中選擇匹配的項反過來,當用戶在列表框中選擇了某個項,程序就自動把當前記錄的該字段的值改為列表框中選擇的值。當然,要使修改有效還必須調用Post函數。
  要在設計期設置列表框中顯示的項,可以單擊Items屬性邊上的省略號按鈕打開一個字符串列表編輯器,然后輸入一些字符串。
  如果IntegralHeight屬性設為True,列表框的高度將總是項的高度的整數倍。
12.4.2 TDBComboBox
  TDBComboBox構件實際上是TComboBox構件的數據感知版本,它能以組合框的形式顯示一組數據,讓用戶從列表中選擇一個值或直接輸入一個值。
  Items屬性用于設置列表中要顯示的一組數據。在設計期,可以單擊Items屬性邊上的省略號按鈕打開一個字符串列表編輯器,然后輸入一些字符串。
  DropDownCount屬性用于設置當用戶下拉組合框時不需要加滾動欄就能顯示的項的個數,默認是8,表示用戶下拉組合框時如果項的個數超過8個才加上滾動欄。如果實際的項數還沒有DropDownCount屬性指定的值多,下拉的組合框的高度自動縮小。
  在Style屬性設為csOwnerDrawFixed的情況下,ItemHeight屬性用于設置項的高度。
12.4.3 顯示另一個數據集中的數據
  TDBLookupListBox構件和TDBLookupComboBox構件分別以列表框和組合框的形式顯示另一個數據集中的數據。
  假設有一個表格叫OrdersTable,其中包含一個CustNo字段,用于表達客戶的編號,但OrdersTable表中除了客戶的編號外,不包含客戶的其他信息。而另一個表格假設叫CustomersTable,除了有CustNo字段外,還有諸如客戶的公司名稱、地址等信息。
  TDBLookupListBox構件可以實現這樣的功能,當用戶在OrdersTable中瀏覽記錄時,程序首先在CustomersTable中查找與CustNo字段匹配的記錄,如果找不到,就從列表中查找與Company字段匹配的字符串;如果找到,就選擇這一項,如圖12.3所示。
  圖12.3 TDBLookupListBox構件的用法
  當用戶在列表中選擇了一項,程序就在CustomersTable中查找與字符串匹配的Company字段,如果找到,就用CustNo字段的值替換OrdersTable表中的CustNo字段。
12.5 用復選框處理布爾類型的字段
   TDBCheckBox構件可以認為是TCheckBox構件的數據感知版本,用于處理布爾類型的字段。例如,可以用一個復選框來表示客戶是否已付帳。
   TDBCheckBox構件實際上是把字段的值與預設的兩個字符串比較,這兩個字符串分別由ValueChecked和ValueUnChecked屬性指定。如果字段的值與ValueChecked屬性指定的字符串匹配,就選中復選框。如果字段的值與ValueUnchecked屬性指定的字符串匹配,就不選中復選框。注意:ValueChecked屬性和ValueUnchecked屬性所指定的字符串不能相同。
  一般情況下,ValueChecked屬性設為“True”、“Yes”之類的字符串,但也可以是其他任意的字符串,甚至是一組字符串,彼此之間要用分號隔開,例如:
  DBCheckBox1.ValueChecked := 'True;Yes;On';
  上述情況下,當字段的值只要與其中一個字符串匹配,就選中復選框。要說明的是,ValueChecked屬性指定的字符串是大小寫敏感的。
  一般情況下,ValueUnchecked屬性設為“False”、“No”之類的字符串,但也可以是其他任意的字符串,甚至是一組字符串,彼此之間用分號隔開。
  如果字段的值既不與ValueChecked屬性指定的字符串匹配,也不與ValueUnchecked屬性指定的字符串匹配,復選框就變灰。
12.6 用單選分組框限制字段的值
   TDBRadioGroup構件可以認為是TRadioGroup構件的數據感知版本,它可以限制用戶從一組數據中選擇字段的值。
   與TRadioGroup構件一樣,首先要設置Items屬性指定單選分組框中要顯示哪些項。Items屬性是一個典型的TStrings對象,每一個字符串對應著單選分組框中的一個按鈕。
  當用戶瀏覽記錄時,如果字段的值與單選分組框中的某個按鈕的標簽匹配,就選擇這個按鈕,如圖12.4所示。
  圖12.4 選擇與CustNo字段的值匹配的單選框
  反過來,當用戶在單選分組框中選擇一個按鈕,程序就用這個按鈕的標簽賦值給DataField屬性指定的字段。
  如果不想使按鈕的標簽與字段的值匹配,可以另外指定其他字符串,這就要用到Values屬性。Values屬性也是一個TStrings對象,用于指定一組字符串。當用戶在單選分組框中選擇一個按鈕,程序就用Values屬性中的一個字符串賦值給DataField屬性指定的字段,而不是按鈕的標簽。
12.7 使用TDBGridTDBGrid構件
  以柵格的形式顯示和編輯數據集中的數據。它的外觀很大程度上取決于下面三個因素:
.一是永久的列對象。
.二是永久的字段對象。
.三是數據集構件的ObjectView屬性將影響ADT和數組字段的顯示方式。
  對于TDBGrid構件來說,最重要的屬性是Columns,這是一個TDBGridColumns對象,用于管理一組TColumn對象。在設計期,可以打開一個編輯器建立永久的列對象,然后在對象觀察器中設置列對象的屬性。
12.7.1動態的列對象
  如果TDBGridColumns的State屬性設為csDefault,列是動態生成的,列的屬性取決于字段的屬性。當字段的屬性發生變化時,列的屬性也跟著變化。
  讓列動態生成的好處是,可以在運行期動態地選擇其他數據集,而不用擔心柵格是否適合于顯示新的數據集。例如,可以用同一個TDBGrid構件先顯示一個Paradox表,再顯示查詢另一個數據庫的結果。
  在設計期,無法直接修改動態列對象的屬性,只能修改字段對象的屬性,從而間接地修改動態列對象的屬性。
  動態列對象的生存期也取決于字段對象的生存期。如果數據集沒有建立永久的字段對象,那么,當數據集關閉時,所有的動態列對象也將消失。
  注意:如果在運行期把TDBGridColumns的State屬性設為csDefault,將刪除所有的列對象,然后根據數據集中的字段對象重建列對象。
12.7.2 永久的列對象
  要能夠在設計期自定義柵格,就要用到永久的列對象。建立了永久的列對象后,如果TDBGridColumns的State屬性設為csCustomized,就可以獨立設置每一列的屬性。例如,默認情況下,列的標題顯示字段的標簽即DisplayLabel屬性,通過修改TColumnTitle的Caption屬性可以重新指定列的標題,而TField的DisplayLabel屬性則不會受到影響。
  TDBGridColumns的State屬性設為csCustomized適合于那些數據集的結構是固定不變的情況。如果需要在運行期切換不同的數據集,就不能把State屬性設為csCustomized。
  要創建永久的列對象,首先要在窗體上選擇TDBGrid構件,然后對象觀察器中單擊Columns屬性邊上的省略號按鈕將打開如圖12.5所示的編輯器。
  圖12.5 創建永久的列對象
  剛開始的時候,這個編輯器是空白的,這是因為,默認情況下,柵格中的列對象都是動態生成的,還沒有永久的列對象。
  要基于數據集中的每一個字段分別創建一個永久的列對象,可以單擊鼠標右鍵,在彈出的菜單中選擇“Add All Fields”命令。
  要創建一個獨立的永久列對象,可以單擊工具欄上的(Add New)按鈕。選擇這個剛創建的列對象,然后在對象觀察器中設置FieldName屬性指定一個字段,設置Caption屬性指定列的標題。
  要刪除一個列對象,可以單擊工具欄上的(Delete Selected)按鈕。如果把永久的列都刪掉,柵格反而能顯示數據集中所有的字段,這是因為,永久的列刪掉以后,Delphi 4會自動把TDBGridColumns的State屬性設為csDefault并且動態生成所有的列。  要調整列在柵格中顯示的順序,可以用鼠標把列對象前移或后移。
  對于永久的列對象來說,它的屬性的默認值仍然取自于字段,除非您修改了永久列對象的屬性。例如,默認的情況下,列的標題就是字段的DisplayLabel屬性。如果修改字段的DisplayLabel屬性,列的標題將隨之改變。但是,一旦您修改了列對象的Caption屬性,列的標題不再與字段的DisplayLabel屬性存在聯動關系,它們彼此是獨立的。
  前面講過,創建一個永久的列對象時,需要設置FieldName屬性指定一個字段。不過,您也可以讓FieldName屬性為空,此時,TColumn對象的Field屬性將返回NULL,并且該列在柵格中是空白的??瞻椎牧型糜谟脩麸@示一些自定義的內容,如圖像或圖表等。
  幾個列對象的FieldName屬性可以設為同一個字段。由此可見,TDBGrid的FieldCount屬性可能小于柵格的列數
12.7.3 讓用戶編輯數據
  對于永久的列對象來說,可以提供幾種方式讓用戶編輯數據。一是以組合框的方式顯示另一個數據集的數據,二是建立一個靜態的列表,三是用省略號按鈕打開一個對話框。
  要以組合框的方式顯示另一個數據集的數據,首先必須在數據集中增加一個Lookup字段,然后創建一個永久的列對象,設置它的FieldName屬性指定這個Lookup字段,并且把它的ButtonStyle屬性設為cbsAuto。經過上述操作后,柵格的效果如圖12.6所示。
  圖12.6 以組合框的形式顯示另一個數據集的數據
  要建立一個靜態的列表,不必事先增加一個Lookup字段,只要先創建一個永久的列對象,把ButtonStyle屬性設為cbsAuto,在對象觀察器中單擊Picklist屬性邊上的省略號按鈕打開一個字符串列表編輯器,然后依次鍵入一些字符串。
  要用一個對話框讓用戶選擇數據,必須把列對象的ButtonStyle屬性設為cbsEllipsis。當程序運行時,該列將出現一個省略號按鈕,單擊這個省略號按鈕將觸發OnEditButtonClick事件,在處理這個事件的句柄中可以打開一個對話框,讓用戶選擇數據。對于圖像字段來說,當用戶單擊省略號按鈕時,可以顯示一個圖像。
12.7.4 在設計期設置列對象的屬性
  列對象的屬性決定了數據在柵格中的顯示方式。在設計期,可以設置它的下列屬性:
.Alignment用于設置數據的對齊方式,默認值是TField的Alignment。
.ButtonStyle設為cbsAuto表示加上一個組合框。設為cbsEllipsis表示加上一個省略號按鈕,當用戶單擊此按鈕將觸發OnEditButtonClick。設為cbsNone表示既沒有組合框也沒有省略號按鈕。
.Color用于設置背景顏色,默認值是TDBGrid的Color。
.DropDownRows 下拉列表框中的項數,默認值是7。
.Expanded如果列對象所對應的字段是ADT或數組字段,這個屬性用于控制是否展開。l FieldName用于指定一個字段,可以讓它空著。
.ReadOnly設為True表示該列是只讀的,不能編輯。
.Width用于設置列的寬度,默認值是TField的DisplayWidth。
.Font用于設置該列中字符的字體,默認值是TDBGrid的Font。
.PickList用于建立一個靜態的列表。
.Title這是個TColumnTitle對象,用于設置列的標題。
  其中,TColumnTitle具有下列屬性:
.Alignment用于設置標題的對齊方式,設為taLeftJustify表示左對齊,設為taCenter表示居中,設為taRightJustify表示右對齊。
.Caption用于指定標題的文字,默認值是TField的DisplayLabel。
.Color用于設置標題的背景顏色,默認值是TDBGrid的FixedColor。
.Font用于設置標題的字體,默認值是TDBGrid的TitleFont。
12.7.5 顯示ADT和數組字段的值
  Delphi 4的TDBGrid構件完全支持Oracle 8的對象字段。
  如果數據集構件的ObjectView屬性設為True,對象字段就可以展開或折疊。當對象字段展開的時候,原來的一列就分為若干列,每一列顯示一個子字段的值,每一個子字段所在的列都有自己的標題欄,這樣可以明顯地看出字段之間的包含關系。當對象字段折疊的時候,就只顯示一個字符串,該字符串列出了每個子字段的值,彼此之間用逗號隔開。
  如果數據集構件的ObjectView屬性設為False,每個子字段與對象字段一樣,都單獨占一列。
  下面介紹幾個與對象字段有關的屬性。一是TColumn的Expandable屬性,如果設為True,表示該列是可展開的。二是TColumn的Expanded屬性,用于測試列當前是否已展開。三是TDBGrid的MaxTitleRows屬性,用于設置柵格中最多可出現幾行標題。四是TDataSet的ObjectView,這個屬性前面已介紹過了。五是TColumn的ParentColumn屬性,用于返回顯示父字段的列對象。
   圖12.7演示了ObjectView屬性設為False的情況:
   圖12.7 ObjectView屬性設為False的情況
   圖12.8演示了ObjectView屬性設為True但對象字段被折疊的情況:
   圖12.8 ObjectView屬性設為True但對象字段被折疊的情況
   圖12.9演示了ObjectView屬性設為True但對象字段被展開的情況:
   圖12.9 ObjectView屬性設為True但對象字段被展開的情況
12.7.6 設置柵格的選項
  可以在設計期設置柵格的選項,這就要用到TDBGrid構件的Options屬性。Options屬性是一個集合,可以包含下列元素:
.dgEditing如果包含這個元素(下同),允許用戶修改柵格中的數據;
.dgAlwaysShowEditor柵格自動處于編輯狀態,否則需按F2才進入編輯狀態;
.dgTitles顯示列的標題;
.dgIndicator當前行的最左端將顯示一個4符號;
.dgColumnResize列的寬度可以重設;
.dgColLines列與列之間用線分開;
.dgRowLines行與行之間用線分開;
.dgTabs可以用Tab鍵和Shift+Tab鍵在列與列之間移動輸入焦點;
.dgRowSelect用戶可以選擇一整行,否則就只能選擇一個單元;
.dgAlwaysShowSelection即使輸入焦點移走,選擇的單元仍然保持選擇狀態;
.dgConfirmDelete按Ctrl+Delete刪除一行時將顯示一個確認框,讓用戶確認;
.dgCancelOnExit在柵格退出的時候,任何未決的修改將被取消
.dgMultiSelect用戶可以在柵格中選擇多行,相當于一個復選的列表框。
12.7.7 在運行期響應用戶的動作
  TDBGrid構件具有幾個事件,用于響應用戶的動作。由于柵格是由行和列構成的,因此,在事件句柄中,首先要區分當前是在哪一列上。下面列出了這些事件:
.OnCellClick當用戶單擊一個單元時將觸發這個事件。
.OnColEnter當輸入焦點進入某一列時將觸發這個事件。
.OnColExit當輸入焦點離開某一列時將觸發這個事件。
.OnColumnMoved當用戶把某一列移到另一個位置時將觸發這個事件。
.OnDblClick當用戶在柵格中雙擊時將觸發這個事件。
.OnDragDrop當用戶在柵格中釋放被拖曳的對象時將觸發這個事件。
.OnDragOver當用戶拖著一個對象經過柵格時將觸發這個事件。
.OnDrawColumnCell當某個單元需要重畫時將觸發這個事件。
.OnDrawDataCell 在State屬性設為csDefault的情況下,當某個單元需要重畫時將觸發這個事件。
.OnEditButtonClick當用戶單擊省略號按鈕時將觸發這個事件。
.OnEndDrag當用戶釋放了鼠標時將觸發這個事件。
.OnEnter當柵格得到輸入焦點時將觸發這個事件。
.OnExit當柵格失去輸入焦點時將觸發這個事件。
.OnKeyDown當用戶按下一個鍵時將觸發這個事件。
.OnKeyPress當用戶按下一個可見的字符鍵時將觸發這個事件。
.OnKeyUp當用戶釋放一個鍵時將觸發這個事件。
.OnStartDrag當用戶開始進行拖放操作時將觸發這個事件。
.OnTitleClick當用戶單擊某一列的標題時將觸發這個事件。
12.7.8 一個特殊的數據庫柵格
  TDBGrid構件的特點是一行只顯示一個記錄,但可以設置每一列的屬性。 TDBCtrlGrid構件的特點是每一行都是一個窗格(TPanel對象),可以在窗格上放一些控件。例如,可以把一個TDBEdit構件放到窗格上,讓它顯示某個字段的值,還可以在編輯框的旁邊加一個TLabel構件作為標簽。TDBCtrlGrid的另一個特點是一行上可以有多個窗格,也就是說,一行可以顯示多個記錄,窗格的高度和寬度都是可以調整的。
  首先,要把一個TDBCtrlGrid構件放到窗體上,設置它的DataSource屬性指定一個TDataSource構件。剛開始的時候,TDBCtrlGrid構件有三行和一列。
  接著,要把一些數據控件放到TDBCtrlGrid構件的“設計單元”上,設置這些數據控件的DataField屬性指定要顯示的字段。
  “設計單元”通常是最上邊或最左邊的那個單元,與其他單元在外觀上的區別是它沒有斜線底紋。
  注意:只能把數據控件放到TDBCtrlGrid構件的“設計單元”上,當程序編譯運行后,會自動把“設計單元”上的數據控件復制到其他單元,每個單元顯示不同的記錄。
  圖12.10演示了TDBCtrlGrid構件的用法:
  圖12.10 TDBCtrlGrid構件的用法
  下面列出了TDBCtrlGrid構件的屬性:
.AllowDelete設為True表示允許刪除記錄。
.AllowInsert設為True表示允許插入記錄。
.ColCount用于設置每一行的窗格數,默認是1。
.Orientation設為goVertical表示從上到下顯示記錄,設為goHorizontal表示從左到右顯示記錄。
.PanelHeight用于設置窗格的高度,默認是72。
.PanelWidth用于設置窗格的寬度,默認是200。
.RowCount用于設置行數,默認是3。
.ShowFocus如果設為True,顯示當前記錄的窗格上有一個虛線邊框。
.SelectedColor用于設置顯示當前記錄的窗格的背景顏色。
12.8 導 航 器
  導航器是用TDBNavigator構件實現的,它可以讓用戶方便地瀏覽和操縱記錄。導航器最多可由10個按鈕組成,包括:
.First第一個記錄;
.Prior前一個記錄;
.Next后一個記錄;
.Last最后一個記錄;
.Insert插入一個空白的記錄;
.Delete刪除當前記錄;
.Edit允許編輯當前記錄;
.Post使未決的編輯操作有效;
.Cancel取消未決的編輯操作;
.Refresh用數據集中的最新的數據刷新記錄。
  可以根據需要,在導航器上有選擇地顯示部分按鈕,這就要用到VisibleButtons屬性。
  在設計期,可以在對象觀察器中選擇要顯示在導航器上的按鈕。在運行期,您可以通過編程選擇要顯示在導航器上的按鈕。例如,假設要用同一個導航器為兩個數據集導航,其中一個允許用戶編輯數據,另一個不允許用戶編輯數據。當在兩個數據集之間切換時,應當動態地改變導航器上的按鈕,因為對于不允許用戶編輯數據的數據集來說,導航器上不應當出現Insert、Delete、Edit、Post、Cancel和Refresh等按鈕。下面代碼把這些按鈕隱藏:
Procedure TForm1.CustomerCompanyEnter(Sender :TObject);
Begin
If Sender = CustomerCompany then
Begin
DBNavigatorAll.DataSource := CustomerCompany.DataSource;
DBNavigatorAll.VisibleButtons := [nbFirst,nbPrior,nbNext,nbLast];
End
Else
Begin
DBNavigatorAll.DataSource := OrderNum.DataSource;
DBNavigatorAll.VisibleButtons := DBNavigatorAll.VisibleButtons + [nbInsert,nbDelete,nbEdit,nbPost,nbCancel,nbRefresh];
End;
End;
  這里順便說一下,當同一個導航器需要為幾個數據集導航時,就要動態地設置DataSource屬性。假設窗體上有兩個TDataSource構件,分別叫CustomersSource和OrdersSource,它們的DataSet屬性分別指定CustomersTable表和OrdersTable表,另外,窗體上有兩個TDBEdit構件,分別叫CustomersEdit和OrdersEdit,它們的DataSource屬性分別指向CustomersSource和OrdersSource。下面這段程序為這兩個TDBEdit構件寫了一個公共的事件句柄來處理OnEnter事件,當用戶在CustomersEdit 上編輯時,導航器將為CustomersTable導航,當用戶在OrdersEdit上編輯時,導航器將為OrdersTable導航。
Procedure TForm1. CustomerEditEnter(Sender: TObject);
Begin
If Sender = CustomerEdit Then
   DBNavigatorl.DataSource := CustomerEdit.DataSource;
Else
DBNavigator1.DataSource := OrderEdit.DataSource;
End;
12.9 數 據 源
  TDataSource構件是一個非可視的構件,它充當了數據集和數據控件之間的橋梁。每一個數據控件都必須指定一個數據源(TDataSource構件),相應地,TDataSource構件的DataSet屬性必須指定一個數據集。下面簡單介紹一下TDataSource構件的屬性和事件。
  DataSet屬性用于指定一個數據集。在設計期,可以在對象觀察器中為DataSet屬性選擇一個數據集。在運行期,可以通過代碼動態地選擇數據集。程序示例如下:
With CustSource Do
Begin
If DataSet = 'Customers' then
DataSet := 'Orders'
Else
DataSet := 'Customers';
End;
  也可以指定另一個窗體上的數據集構件,例如:
Procedure TForm2. FormCreate (Sender : TObject);
Begin
DataSource1.Dataset := Form1.Table1;
End;
  一般情況下,TDataSource構件的名稱是無關緊要的。不過,TDataSource構件的名稱應當能反映它所連接的數據集,例如,假設TDataSource構件連接的數據集叫Customers,相應地,TDataSource構件的名稱最好叫CustomersSource。
  Enabled屬性用于控制TDataSource構件是否與數據集連接,設為True表示連接,設為False表示暫時斷開連接。如果Enabled屬性設為False,凡是連接于這個數據源的數據控件將變成空白。
  如果AutoEdit屬性設為True,當用戶在數據控件中鍵入字符時,數據集就自動進入dsEdit狀態。如果AutoEdit屬性設為False,程序必須調用Edit函數才能進入dsEdit狀態。
  當數據集的當前記錄的位置發生變化時將觸發OnDataChange事件,這可能是因為程序調用了Next、Previous、Insert等方法。
  當前記錄的數據將要被更新時將觸發OnUpdateData事件,這可能是因為調用了Post。在處理這個事件的句柄中,可以對數據進行校驗。
  當State屬性發生變化時將觸發OnStateChange事件。例如,可以用一個標簽動態地顯示當前的狀態。程序示例如下:
ProcedureTForm1.DataSource1.StateChange(Sender:TObject);
var
S:String;
Begin
Case CustTable.State of
dsInactive: S := 'Inactive';
dsBrowse: S := 'Browse';
dsEdit: S := 'Edit';
dsInsert: S := 'Insert';
dsSetKey: S := 'SetKey';
End;
CustTableStateLabel.Caption := S;
End;
  利用OnStateChange事件也可以動態地允許或禁止按鈕和菜單項,程序示例如下:
Procedure Form1.DataSource1.StateChange(Sender: TObject);
Begin
CustTableEditBtn.Enabled := (CustTable.State = dsBrowse);
CustTableCancelBtn.Enabled := CustTable.State in [dsInsert, dsEdit, dsSetKey];
...
End;

上一篇:多層數據庫開發十三:剖析幾個數據庫應用程序

下一篇:多層數據庫開發九:查詢數據庫

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
學習交流
熱門圖片

新聞熱點

疑難解答

圖片精選

網友關注

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品久久久久久久app| 国产精品福利网| 国产精品igao视频| 成人国产精品久久久| 欧美激情一级精品国产| 日韩视频在线免费观看| 亚洲一区二区三区四区在线播放| 国产91色在线|| 亚洲已满18点击进入在线看片| 亚洲欧美制服丝袜| 成人av色在线观看| 91高清在线免费观看| 亚洲欧美日韩一区在线| 91国语精品自产拍在线观看性色| 国产精品成人av性教育| 欧美激情精品久久久| 亚洲欧美综合图区| 亚洲人午夜色婷婷| 日韩在线视频导航| 青草青草久热精品视频在线观看| 国产中文字幕日韩| 欧美福利视频在线观看| 精品国模在线视频| 国产精品99蜜臀久久不卡二区| 国产精品视频资源| 国产极品jizzhd欧美| 欧美成人亚洲成人| 日韩国产在线播放| 欧美人成在线视频| 国产精品va在线播放我和闺蜜| 欧美激情aaaa| 国产美女扒开尿口久久久| 欧美视频裸体精品| 色婷婷久久一区二区| 美女福利视频一区| 中文字幕亚洲在线| 亚洲欧美日韩在线高清直播| 久久国产精品99国产精| 久久久久久欧美| 青青久久av北条麻妃黑人| 国产日韩av在线播放| 久久噜噜噜精品国产亚洲综合| 日韩av资源在线播放| 欧美成人手机在线| 57pao成人永久免费视频| 欧美日韩第一页| 亚洲第一视频网站| 狠狠久久五月精品中文字幕| 九九精品在线视频| 亚洲国产美女精品久久久久∴| 狠狠躁夜夜躁久久躁别揉| 久久视频在线播放| 中文字幕亚洲自拍| 九色精品美女在线| 亚洲欧美另类国产| 国产精品人成电影在线观看| 欧美黑人巨大精品一区二区| 久久久久久久久久久久久久久久久久av| 亚洲一区二区三区视频播放| 九色成人免费视频| 国产精品久久久久久久久久久久久久| 国产精品丝袜高跟| 日本高清+成人网在线观看| 色多多国产成人永久免费网站| 久久精品亚洲一区| 欧美视频在线观看免费| 91探花福利精品国产自产在线| 91在线观看免费观看| 欧美激情亚洲国产| 久久视频免费在线播放| 色综合色综合久久综合频道88| 欧美一区二区三区免费视| 国产在线精品播放| 高清一区二区三区四区五区| 岛国av一区二区三区| 亚洲国产精品va| 成人深夜直播免费观看| 日韩av在线影视| 日本a级片电影一区二区| 韩国一区二区电影| 操日韩av在线电影| 日韩av综合中文字幕| 日韩av在线资源| 亚洲成人网在线| 欧美极品欧美精品欧美视频| 国产丝袜精品第一页| 欧美日本中文字幕| 亚洲精品天天看| 亚洲第一区在线观看| 午夜精品福利在线观看| 97超级碰在线看视频免费在线看| 2018中文字幕一区二区三区| 久久久免费在线观看| 日本不卡高字幕在线2019| 久久精品国产亚洲精品| 国产精品扒开腿做爽爽爽男男| 91中文在线视频| 2025国产精品视频| 色哟哟网站入口亚洲精品| 91网站在线免费观看| 日本亚洲精品在线观看| 欧美激情视频在线观看| 91久久久久久久| 亚洲小视频在线| 欧美性生交xxxxx久久久| 青草青草久热精品视频在线观看| 国产69精品久久久久久| 亚洲在线观看视频| 久久91亚洲精品中文字幕| 国产69精品久久久久久| 亚洲综合日韩在线| 久久精品在线播放| 日韩电影免费在线观看中文字幕| 国产精品私拍pans大尺度在线| 日韩二区三区在线| 丰满岳妇乱一区二区三区| 日韩美女激情视频| 亚洲成人av在线| 色综久久综合桃花网| 亚洲国产成人精品一区二区| 欧美精品在线观看| 欧美日韩另类字幕中文| www.美女亚洲精品| 欧美性生交大片免费| 亚洲精品有码在线| 亚洲乱码一区二区| 欧美猛少妇色xxxxx| 国产精品激情自拍| 欧美夫妻性生活视频| 欧美成人免费在线观看| 97激碰免费视频| 中文字幕亚洲第一| 亚洲色在线视频| 欧美丰满少妇xxxxx| 亚洲精品资源美女情侣酒店| 日韩在线观看免费av| 国产在线视频91| 狠狠色狠狠色综合日日小说| 中文字幕av日韩| 久久人人爽人人爽人人片亚洲| 精品久久久久久久大神国产| 中文字幕日韩欧美在线| 97在线日本国产| 欧美多人乱p欧美4p久久| 精品一区二区三区电影| 九九热99久久久国产盗摄| 一本色道久久88综合亚洲精品ⅰ| 亚洲影院色在线观看免费| 亚洲精品小视频在线观看| 欧美精品电影免费在线观看| 久久久女人电视剧免费播放下载| 九九精品视频在线| 在线观看国产成人av片| 在线播放亚洲激情| 国产一区二区三区直播精品电影| 亚洲最新av在线| 日韩有码视频在线| 国产视频精品自拍| 亚洲一区二区三区乱码aⅴ| 欧美另类高清videos| 91天堂在线观看| 中文字幕一精品亚洲无线一区| 97福利一区二区| 日韩高清电影免费观看完整版|