RAD Studio 10.4.1 is now available! Learn more. Looking for discounts? Visit our Special Offers page!
News

Making Win10 Calendar controls database-aware

Author: Dmitry Kovalenko

Programming is fun. Sometimes projects and apps are more serious, sometimes less. On my recent Delphi 10.1 Update 2 presentation two times I have been asked about data-aware versions of new VCL Win10 calendar controls. Here is the code.


unit uDBCalendarView;

interface

uses
  System.Classes, Vcl.WinXCalendars, Data.DB, VCL.DBCtrls;

type
  TDBCalendarView = class(TCalendarView)
  private
    FDataLink: TFieldDataLink;
    procedure DataChange(Sender: TObject);
    procedure SetDataField(const Value: string);
    procedure SetDataSource(const Value: TDataSource);
    function GetDataField: string;
    function GetDataSource: TDataSource;
    function GetField: TField;
    function GetFieldDate: TDate;
  protected
    procedure Loaded; override;
    procedure Notification(AComponent: TComponent;
      Operation: TOperation); override;
  public
    constructor Create(AOwner: TComponent);
    destructor Destroy; override;
    property Field: TField read GetField;
  published
    property DataField: string read GetDataField write SetDataField;
    property DataSource: TDataSource read GetDataSource write SetDataSource;
  end;

implementation

uses
  System.SysUtils;

{ TDBCalendarView }

constructor TDBCalendarView.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Enabled := False; // read-only
  FDataLink := TFieldDataLink.Create;
  FDataLink.Control := Self;
  FDataLink.OnDataChange := DataChange;
end;

destructor TDBCalendarView.Destroy;
begin
  FDataLink.Free;
  inherited;
end;

procedure TDBCalendarView.Loaded;
begin
  inherited Loaded;
  if (csDesigning in ComponentState) then DataChange(Self);
end;

procedure TDBCalendarView.Notification(AComponent: TComponent;
  Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);
  if (Operation = opRemove) and (FDataLink <> nil) and
    (AComponent = DataSource) then DataSource := nil;
end;

procedure TDBCalendarView.DataChange(Sender: TObject);
begin
  self.Date := GetFieldDate;
end;

function TDBCalendarView.GetField: TField;
begin
  Result := FDataLink.Field;
end;

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

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

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

procedure TDBCalendarView.SetDataSource(const Value: TDataSource);
begin
  if not (FDataLink.DataSourceFixed and (csLoading in ComponentState)) then
    FDataLink.DataSource := Value;
  if Value <> nil then Value.FreeNotification(Self);
end;

function TDBCalendarView.GetFieldDate: TDate;
begin
  if FDataLink.Field <> nil then
  begin
    if (FDataLink.Field.DataType in [ftDate, ftDateTime, ftTimeStamp, ftTime]) then
      Result := FDataLink.Field.AsDateTime
    else
      Result := Now;
  end
  else
    if csDesigning in ComponentState then Result := Now;
end;

end.

One of the best things about Delphi is that it comes with the source code. After a lot of googling for examples of custom database aware Delphi components, the actual source code of “TDBText” component in “VCL.DBCtrls” unit was the best resource.

The most important part of a custom data-aware field component is private “TFieldDataLink”. It does all the job, but as component implementer you need to expose its “DataSource” and “FieldName” properties. In the constructor there is also “OnDataChanged” event connected to “DataChanged” procedure. In this way the calendar control knows when it needs to refresh itself. This is centralized in the “GetFieldDate” method that reads the date from the internal “FDataLink.Field”.

Not a rocket science:-)

The source code of custom Win10 VCL data-aware components can be downloaded from this link.

The test application of data-aware “TCalendarView” and “TCalendarPicker” looks like this and is using RAD Studio InterBase “EMPLOYEE” database.

   


Reduce development time and get to market faster with RAD Studio, Delphi, or C++Builder.
Design. Code. Compile. Deploy.
Start Free Trial   Upgrade Today

   Free Delphi Community Edition   Free C++Builder Community Edition

Related posts
C++

What's New in the GetIt Package Manager - June 2020

C++

RAD Studio 10.4 Now Available, Learn More

C++NewsRAD Studio

Open for Business with 10.4! - May 2020 GM Update

C++DelphiNews

Embarcadero Open Source Project Sponsorship

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

IN THE ARTICLES