動態

詳情 返回 返回

# 一步一步學習使用LiveBindings(10) LiveBindings綁定到漂亮的TCombobox - 動態 詳情

這一課,將演示如何綁定到TCombobox,這個控件通常用來給用户提供選項列表。它們具有比VCL控件較強的定製性,可以使用樣式窗口對每一個項進行外觀的定製。

如果讀者已經看過《一步一步學習使用LiveBindings(9)》,那應該會比較熟悉這一課的案例,因為筆者將上一節的案例LiveBindings_BindFormat的源代碼複製到了這一節作為起點。

在上一節的員工管理窗口中,有一個Title職位字段,在真實的項目這個字段應該是一個下列拉表框供用户選擇,而不是一個文本輸入框,以避免用户胡亂輸入太多的職位而無法管理,效果如下所示:

img
我們通常會有一個表來存放職位信息,接下來一步一步演示如何實現從數據源到Combobox下拉表列框的綁定。

1. 打開LiveBindings_BindFormat項目的主窗體,從工具欄中拖一個TProtoTypeBindSource控件到主窗體上,將其命名為TitleBindSource,然後右擊該控件,打開Fields Editor,定義如下的幾個字段和生成器。

img

幾個字段的作用如下:

  • ContactTitle:職位名稱
  • TitleImageIndex:職位的圖片索引,演示如何給Combobox綁定一張圖片。
  • TitleDescription:職位描述
  • TitleColor:將用於職位的顏色。

2. 在主窗體上右擊鼠標,從彈出的菜單中選擇“LiveBinding Wizard...”,使用嚮導,選擇“Link a Control with a field”菜單項,創一個新的TCombobox到數據源TitleBindSource的連接,指定FieldName為ContactTitle,嚮導會自動將Combobox控件的Synch與TitleBindSource的*進行連接,並有一個指向Item.Text的單向連接。

img

綁定的連接是一個類型為TLinkListControlToField連接類型,FireMonkey的ListBox、ListView都會使用這種類型來綁定數據。

設計器中的Combobox除了Synch之外,還有如下的幾個可綁定類型:

  • SelectedValue:當選中項時,SelectedValue返回的給其他數據源的數據。
  • Item.Text:顯示在Combobox中的項的文本。
  • Item.ImageIndex:顯示在Combobox的圖片索引。
  • Item.LookupData:SelectedValue將返回的值類型,也就是要搜尋的數據。

在這裏需要將SelectedValue連接到EmployeeBindSource控件的Title字段,以便將當前選中的Contact Title更新到EmployeeBindSource的底層表。

在設計器中拖動SelectedValue到EmployeeBindSource控件的Title字段,設計器會彈出一個提示:

img

嚮導會刪除Synch到*的連接,接下來將如下圖連接Item.ImageIndex,並指定Item.LookupData到ContactTitle,以確保SelectedValue會返回職位名稱。

img

3. 選中Combobox控件,指定其Images屬性為一個TImageList,這樣就會在列表項左側顯示圖片。

最終效果如下所示:

img

4. 在代碼部分,更新了EmployeeObjectU.pas,添加了一個新的類TEmployeeTitle,現附上更新後的代碼

EmployeeObjectU.pas

unit EmployeeObjectU;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, System.StrUtils;

type
  TEmployee = class
  private
    FContactBitmap: TBitmap;      //聯繫人圖片
    FContactName: string;         //聯繫人名稱
    FTitle: string;               //職位
    FHireDate: TDate;             //僱傭日期
    FSalary: Integer;             //薪水
    FAvailNow: Boolean;           //是否在職
  public
    constructor Create(const NewName: string;
                       const NewTitle: string;
                       const NewHireDate: TDate;
                       const NewSalary: Integer;
                       const NewAvail: Boolean);
    property ContactBitmap: TBitmap read FContactBitmap write FContactBitmap;
    property ContactName: string read FContactName write FContactName;
    property Title: string read FTitle write FTitle;
    property HireDate: TDate read FHireDate write FHireDate;
    property Salary: Integer read FSalary write FSalary;
    property AvailNow: Boolean read FAvailNow write FAvailNow;
  end;

type
  TEmployeeTitle = class
  private
    FContactTitle: string;                 //職位名稱
    FTitleColor: Cardinal;                 //顯示顏以
    TTitleImageIndex: Integer;             //顯示圖標索引
    TTitleDescription: string;             //職位描述
  public
    constructor Create(const NewTitle: string;
                       const NewTitleDesc: string;
                       const NewTitleColor: Cardinal;
                       const NewImageIdx: Integer);
    property ContactTitle: string read FContactTitle write FContactTitle;
    property TitleColor: Cardinal read FTitleColor write FTitleColor;
    property TitleImageIndex: Integer read TTitleImageIndex write TTitleImageIndex;
    property TitleDescription: string read TTitleDescription write TTitleDescription;
  end;


implementation

{ TEmployee }

constructor TEmployee.Create(const NewName, NewTitle: string;
  const NewHireDate: TDate; const NewSalary: Integer; const NewAvail: Boolean);
var
  NewBitmap: TBitmap;
  ResStream: TResourceStream;
begin
  //將根據聯繫人名稱姓來關聯資源文件
  ResStream := TResourceStream.Create(HINSTANCE, 'Bitmap_' + LeftStr(NewName, Pos(' ', NewName) - 1), RT_RCDATA);
  try
    NewBitmap := TBitmap.Create;
    NewBitmap.LoadFromStream(ResStream);
  finally
    ResStream.Free;
  end;

  FContactName   := NewName;
  FTitle         := NewTitle;
  FContactBitmap := NewBitmap;       //來自資源的圖片
  FHireDate      := NewHireDate;
  FSalary        := NewSalary;
  FAvailNow      := NewAvail;
end;


{ TEmployeeTitle }

constructor TEmployeeTitle.Create(const NewTitle, NewTitleDesc: string;
  const NewTitleColor:Cardinal;const NewImageIdx: Integer);
begin
  FContactTitle   := NewTitle;
  FTitleColor     := NewTitleColor;
  TTitleImageIndex := NewImageIdx;       //來自TImageList的圖片
  TTitleDescription:= NewTitleDesc;
end;

end.

在主窗體中,為TitleBindSource的OnCreateAdapter事件添加了如下的代碼來:

procedure TfrmMain.TitleBindSourceCreateAdapter(Sender: TObject;
  var ABindSourceAdapter: TBindSourceAdapter);
begin
  bsEmployeeTitle:= TListBindSourceAdapter<TEmployeeTitle>.Create(self, nil, True);
  //賦值給TBindSourceAdapter
  ABindSourceAdapter := bsEmployeeTitle;
end;

在FormCreate中關聯了List.

procedure TfrmMain.FormCreate(Sender: TObject);
begin
  LoadData;  //加載數據
  //設置員工列表
  bsEmployee.SetList(FEmployeeList, False);
  bsEmployee.Active := True;
  //設置員工編號列表
  bsEmployeeTitle.SetList(FEmployeeTitleList, False);
  bsEmployeeTitle.Active := True;
end;

最後,選中Combobox控件,設置DropDownKind為Custom,然後添加LinkFillControlToField.OnFillingListItem事件,讓其在填充列表項時,指定一個列表項的樣式:

procedure TfrmMain.LinkFillControlToFieldFillingListItem(Sender: TObject;
  const AEditor: IBindListEditorItem);
begin
  //指定列表項的樣式
  (AEditor.CurrentObject as TListBoxItem).StyleLookup :='listboxitembottomdetail';
end;

listboxitembottomdetail是內置的列表項的樣式,它需要指定Item.text和Item.Detail的值。

TLinkFillControlToField的ListItemStyle為ItemDataEditor,這樣在LiveBindings Designer設計視圖中就會顯示Item.Detail和Item.Bitmap以及Item.Accessory,將Item.Detail綁定到TitleDescription即可。

img

顯示效果如下所示:

img

選擇使用FireMonkey的程序員,一定會被其強大的自定義樣式定義所吸引,在接下來的課程中,將會討論如何自定義樣式。

Add a new 評論

Some HTML is okay.