4.2 多頁面界面
多頁面界面是一種非常友好的界面形式。它由一個窗體和多個頁面組成, 關於每個頁面的信息列在窗體底部的標簽(Tabs)上,用戶可通過選擇標簽來進行頁面切換。 每次只有一個頁面顯示在窗體中。MPI較MDI使用更為方便,且切換速度更快。本章例程就是多頁面界面的例子。另外Delphi集成開發環境中的代碼編輯(Code Editor)窗體是MPI應用在文本編輯中的實例。在MPI中,一個窗體內的多個文件可以方便地進行切換和交換數據。
多頁面界面分為靜態MPI和動態MPI兩種形式。靜態MPI的標簽數量固定,用戶在事先設計好的多個頁面上進行切換。象選擇對話框(Option Dialog)就屬於靜MPI。動態MPI的標簽數量不固定,由程序根據需要動態的產生或消除,象代碼編輯窗體就是動態MPI,程序可根據用戶的需要產生多個文本頁面,也可以動態地關閉頁面。利用Delphi的TNotebook和Ttabset 可十分方便地設計靜態MPI。設計動態MPI則需要編寫專門的代碼。
4.2.1 靜態多頁面界面
TNotebook,TTabSet可用來開發靜態多頁面界面。TNotebook部件能顯示多頁, 每頁都有相應的控制。通常TNotebook與TTabset配合進行控制。TTabset 有一組水平的標簽,每個標簽可通過創建字符串列表進行某種控制。
MPIEDit例程中的主窗體中有一個TNotebook 部件和 TTabSet 部件。 把兩個部件的Aglin屬性設置成bsTop和bsBotton,使它們分別處在窗體的上下兩部分。為了使TTabSet與TNotebook配合工作,使用下代碼:
TabSet1.Tabs := Notebook1.Page;
另外,在TabSet的OnClick事件中定義下如下代碼,可使用戶在選擇標簽時開打相應的頁。
procedure TEditForm.TabSetClick(Sender : TObject);…
begin
Notebook1.PageIndex := TabSet1.TabIndex;
…
end;
設計靜態MPI時,可在部件窗體(Component Palette)的WIN3。1頁面中選中TNotebook 部件,然後在Object inspector窗體中雙擊TNotebook的Pages屬性,Dephi 將彈出對話框,用戶可以在此確定Notebook的頁數和字符串列表,如圖4.6。關閉對話框後, 可對每一頁進行設計,使用鼠標右按鈕彈出快速菜單進行頁面切換。
4.2.2 動態多頁面界面
使用Delphi進行靜態MPI設計非常簡單,進行動態MPI設計則需編寫專門的代碼。 對
於一個多頁面文本編輯器,應能實現以下功能:
● 動態生成頁面,每個頁面均能進行文本編輯
● 動態關閉頁面,直到窗體中只有一個頁面為止
● 頁面切換不影響各種文本編輯操作
為了實現以上功能,程序中使用了動態頁面類(TDynaPage),其定義如下:
type TDynaPage = Class(TObject);
該類可根據需要動態的產生頁面, 每個頁面上創建了可進行文本編輯的TMeno部件。
procedure...
puclic
CurPage : integer;
FileList : TSringList;
end;
CurPage表示當前用戶選擇的頁面數,用戶切換、增加、刪除頁面均影響CurPage 的值,CurPage初如化為零頁。FileList存放打開或創建文件的名字以及與這些文件相關的編輯部件TMemo,頁面動態創建、刪除將影響FilstList的值。
TNotebook部件創建後至少有一個頁面,因此Pages屬性不是空值,只要往Pages中加入字符串,Delphi自動地把該字符串與TPage類對象相聯系。TPage類是TCustomEdit派生出來的,在對象浏覽器(Object Browse)中可觀察到TPage的數據成員和方法。靜態生成的頁面也是 TPage類。
要創建多頁面編輯器,必須從TPage的父件(Parent屬件)創建相應編輯部件。但在動態創建頁面時,TPage只是一個與字符串相聯系的TObject類,不能寫成:
MemoParent := Notebook1.Pages.Object[ ];
在Delphi中,宣稱對象和創建對象都是用指針來標識, 因此可用無類型指針進行指針傳遞。
var
Pi : Pointer;
begin
Pi := Notebook1.Pages.Object[];
Memo.Parent := Pi;
end;
這樣就可在TPage上動態創建編輯部件了。
往Notebook1中動態生成頁面時,頁面應所相應的切換,TDynaPage. Notebook1.Tabset1有關的屬性要作相應的調整。
TDynaPage的DynaAdd方法定義如下:
procedure TDynaPage.DynaAdd(Sender:TNotebook;FileName:String);
var
Pi:Pointer;
Memo:TMemo;
begin
Sender.Pages.add(FileName);
Pi:= Sender.Pages.Objects[Sender.Pages.Count-1];
DynaMemo(pi);
DynaPage.FileList.addObject(FileName,Memo1);
EditForm.TabSet1.Tabs := Sender.Pages;
EditForm.Tabset1.TabIndex:=Sender.Pages.Count-1;
EditForm.Notebook1.PageIndex := EditForm.Tabset1.TabIndex;
DynaPage.CurPage:= Sender.Pages.Count-1;
end;
procedure DynaMemo(Pi:Pointer);
var
Memo:TMemo;
begin
Memo:=TMemo.Create(Pi);
Memo.Parent:=Pi;
Memo.Align:=alClient;
Memo.borderStyle:=bsNone;
Memo.HideSelection:=False;
Memo1:=Memo;
end;
procedure TDynaPage.Del(Sender:TNotebook;No:integer);
var
Pi:pointer;
begin
Sender.Pages.delete(No);
EditForm.TabSet1.Tabs.delete(No);
Filelist.Delete(No);
DynaPage.CurPage:=EditForm.TabSet1.TabIndex;
Sender.PageIndex := EditForm.Tabset1.TabIndex;
Pi:=FileList.Objects[DynaPage.CurPage];
Memo1:=Pi;
EditForm.Caption:=Sender.Pages.Strings[DynaPage.CurPage];
end;