首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> Delphi

Delphi 資料感知日曆元件:唯讀屬性實作、更新旗標機制與 DataSource/DataField 屬性發布

     編輯:Delphi

19.3.1.2 打造真正的唯讀日曆:雙重保障機制

1. 唯讀屬性與 SelectCell 覆寫


type
  TDBCalendar = class(TCalendar)
  private
    FReadOnly: Boolean;
  published
    property ReadOnly: Boolean read FReadOnly write FReadOnly default True;
  end;

constructor TDBCalendar.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FReadOnly := True;
end;

function TDBCalendar.SelectCell(ACol, ARow: Longint): Boolean;
begin
  if FReadOnly then Result := False  // 封鎖使用者選擇
  else Result := inherited SelectCell(ACol, ARow);
end;

設計期預設 ReadOnly = True,SelectCell 回傳 False 直接取消儲存格進入,滑鼠/鍵盤操作完全無效。

2. 更新旗標:允許程式內部修改選擇位置

問題:UpdateCalendar 內部設定 Row/Col 同步日期顯示,但被 SelectCell 封鎖。

解決:引入 FUpdating 旗標區分使用者操作與程式更新:


type
  TDBCalendar = class(TCalendar)
  private
    FUpdating: Boolean;
  protected
    function SelectCell(ACol, ARow: Longint): Boolean; override;
  public
    procedure UpdateCalendar; override;
  end;

function TDBCalendar.SelectCell(ACol, ARow: Longint): Boolean;
begin
  if (not FUpdating) and FReadOnly then Result := False
  else Result := inherited SelectCell(ACol, ARow);
end;

procedure TDBCalendar.UpdateCalendar;
begin
  FUpdating := True;
  try
    inherited UpdateCalendar;  // 正常同步 Row/Col
  finally
    FUpdating := False;        // 保證旗標重置
  end;
end;

try...finally 確保異常情況下旗標必歸零,避免永久解除唯讀保護。

3. 發布 DataSource 與 DataField 屬性:標準資料感知介面


type
  TDBCalendar = class(TCalendar)
  private
    FDataLink: TFieldDataLink;
    function GetDataField: string;
    function GetDataSource: TDataSource;
    procedure SetDataField(const Value: string);
    procedure SetDataSource(Value: TDataSource);
  published
    property DataField: string read GetDataField write SetDataField;
    property DataSource: TDataSource read GetDataSource write SetDataSource;
  end;

function TDBCalendar.GetDataField: string;
begin Result := FDataLink.FieldName; end;

function TDBCalendar.GetDataSource: TDataSource;
begin Result := FDataLink.DataSource; end;

procedure TDBCalendar.SetDataField(const Value: string);
begin FDataLink.FieldName := Value; end;

procedure TDBCalendar.SetDataSource(Value: TDataSource);
begin FDataLink.DataSource := Value; end;

委派給 FDataLink 同名屬性,零邏輯薄封裝,符合 VCL 資料感知元件標準契約。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved