⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unboundexternaldatademoclasses.pas

📁 DevExpress ExpressQuantumGrid Suite v5.9 Full Source
💻 PAS
字号:
unit UnboundExternalDataDemoClasses;

{$I ..\..\cxVer.inc}

interface

uses
  Windows, Classes, SysUtils, cxCustomData {$IFDEF DELPHI6}, Variants{$ENDIF};

type

  TUserIniFile = class(TObject)
  private
    FFileName: string;
    FModified: Boolean;
    FSections: TStringList;
    FOnModify: TNotifyEvent;
    function GetSectionName(AIndex: Integer): string;
    procedure ReleaseSection(AIndex: Integer);
    procedure SetModified(AValue: Boolean);
  public
    constructor Create(const AFileName: string);
    destructor Destroy; override;
    procedure ChangeSectionName(AIndex: Integer; const ASection: string);
    procedure Clear;
    procedure DeleteSection(AIndex: Integer);
    function InsertSection(AIndex: Integer; const ASection: string;
      AAppend: Boolean = False): TStrings;
    procedure LoadValues; overload;
    procedure LoadValues(AList: TStrings); overload;
    procedure Rename(const AFileName: string; AReload: Boolean);
    procedure SaveAs(const AFileName: string);
    procedure SaveValues; overload;
    procedure SaveValues(AList: TStrings); overload;
    function SectionCount: Integer;
    property FileName: string read FFileName;
    property Modified: Boolean read FModified write SetModified;
    property SectionNames[AIndex: Integer]: string read GetSectionName;
    property Sections: TStringList read FSections;
    property OnModify: TNotifyEvent read FOnModify write FOnModify;
  end;

  TUserDataSource = class(TcxCustomDataSource)
  private
    FIniFile: TUserIniFile;
  protected
    function GetRecordCount: Integer; override;
    function GetValue(ARecordHandle: TcxDataRecordHandle;
      AItemHandle: TcxDataItemHandle): Variant; override;
    procedure SetValue(ARecordHandle: TcxDataRecordHandle;
      AItemHandle: TcxDataItemHandle; const AValue: Variant); override;
  public
    constructor Create(AIniFile: TUserIniFile);
    function AppendRecord: TcxDataRecordHandle; override;
    function InsertRecord(ARecordHandle: TcxDataRecordHandle): TcxDataRecordHandle; override;
    procedure DeleteRecord(ARecordHandle: TcxDataRecordHandle); override;
    property DataIniFile: TUserIniFile read FIniFile;
  end;

  TUserDetailDataSource = class(TcxCustomDataSource)
  private
    FDataSource: TUserDataSource; // master
  protected
    function GetRecordCount: Integer; override;
    function GetValue(ARecordHandle: TcxDataRecordHandle; AItemHandle: TcxDataItemHandle): Variant; override;
    procedure SetValue(ARecordHandle: TcxDataRecordHandle;
      AItemHandle: TcxDataItemHandle; const AValue: Variant); override;
  public
    constructor Create(ADataSource: TUserDataSource);
    function AppendRecord: TcxDataRecordHandle; override;
    function InsertRecord(ARecordHandle: TcxDataRecordHandle): TcxDataRecordHandle; override;
    procedure DeleteRecord(ARecordHandle: TcxDataRecordHandle); override;
    function GetMasterRecordIndex: Integer;
    property MasterDataSource: TUserDataSource read FDataSource;
  end;

implementation

{ TUserIniFile }

constructor TUserIniFile.Create(const AFileName: string);
begin
  inherited Create;
  FSections := TStringList.Create;
  FFileName := AFileName;
end;

destructor TUserIniFile.Destroy;
begin
  Clear;
  FSections.Free;
  inherited;
end;

procedure TUserIniFile.ChangeSectionName(AIndex: Integer;
  const ASection: string);
begin
  Sections[AIndex] := ASection;
end;

procedure TUserIniFile.Clear;
var
 I: Integer;
begin
  for I := 0 to SectionCount - 1 do
    ReleaseSection(I);
  Sections.Clear;
end;

procedure TUserIniFile.DeleteSection(AIndex: Integer);
begin
  ReleaseSection(AIndex);
  Sections.Delete(AIndex);
end;

function TUserIniFile.InsertSection(AIndex: Integer; const ASection: string;
  AAppend: Boolean = False): TStrings;
begin
  if ASection = '' then
  begin
    Result := nil;
    Exit;
  end;
  Result := TStringList.Create;
  try
    if AAppend then
      Sections.AddObject(ASection, Result)
    else
      Sections.InsertObject(AIndex, ASection, Result);
  except
    FreeAndNil(Result);
  end;
end;

procedure TUserIniFile.LoadValues;
var
  AList: TStringList;
begin
  AList := TStringList.Create;
  try
    if FileExists(FileName) then
      AList.LoadFromFile(FileName);
    LoadValues(AList);
  finally
    AList.Free;
  end;
end;

procedure TUserIniFile.LoadValues(AList: TStrings);
var
  I: Integer;
  S: string;
  ASection: TStrings;
  AEqualityPos: Integer;
begin
  Clear;
  ASection := nil;
  for I := 0 to AList.Count - 1 do
  begin
    S := Trim(AList[I]);
    if (S <> '') and (S[1] <> ';') then
      if (S[1] = '[') and (S[Length(S)] = ']') then
        ASection := InsertSection(-1, Trim(Copy(S, 2, Length(S) - 2)), True)
      else
        if ASection <> nil then
        begin
          AEqualityPos := Pos('=', S);
          if AEqualityPos > 0 then
            ASection.Add(TrimRight(Copy(S, 1, AEqualityPos - 1)) + '=' + TrimLeft(Copy(S, AEqualityPos + 1, MaxInt)))
          else
            ASection.Add(S);
        end;
  end;
  Modified := False;
end;

procedure TUserIniFile.Rename(const AFileName: string; AReload: Boolean);
begin
  FFileName := AFileName;
  if AReload then
    LoadValues;
end;

procedure TUserIniFile.SaveAs(const AFileName: string);
begin
  Rename(AFileName, False);
  SaveValues;
end;

procedure TUserIniFile.SaveValues;
var
  AList: TStringList;
begin
  AList := TStringList.Create;
  try
    SaveValues(AList);
    AList.SaveToFile(FileName);
  finally
    AList.Free;
  end;
end;

procedure TUserIniFile.SaveValues(AList: TStrings);
var
  I, J: Integer;
  ASection: TStrings;
begin
  for I := 0 to SectionCount - 1 do
  begin
    AList.Add('[' + SectionNames[I] + ']');
    ASection := TStrings(FSections.Objects[I]);
    for J := 0 to ASection.Count - 1 do
      AList.Add(ASection[J]);
    if I < SectionCount - 1 then
      AList.Add('');
  end;
  Modified := False;
end;

function TUserIniFile.SectionCount: Integer;
begin
  Result := Sections.Count;
end;

function TUserIniFile.GetSectionName(AIndex: Integer): string;
begin
  Result := Sections[AIndex];
end;

procedure TUserIniFile.ReleaseSection(AIndex: Integer);
begin
  Sections.Objects[AIndex].Free;
end;

procedure TUserIniFile.SetModified(AValue: Boolean);
begin
  if Assigned(OnModify) then
    FOnModify(Self);
  if FModified <> AValue then
    FModified := AValue;
end;

{ TUserDataSource }

constructor TUserDataSource.Create(AIniFile: TUserIniFile);
begin
  inherited Create;
  FIniFile := AIniFile;
end;

procedure TUserDataSource.DeleteRecord(ARecordHandle: TcxDataRecordHandle);
begin
 with DataIniFile do
 begin
   DeleteSection(Integer(ARecordHandle));
   Modified := True;
 end;
 DataChanged;
end;


function TUserDataSource.GetRecordCount: Integer;
begin
  Result := DataIniFile.Sections.Count;
end;

function TUserDataSource.GetValue(ARecordHandle: TcxDataRecordHandle;
  AItemHandle: TcxDataItemHandle): Variant;
begin
  Result := DataIniFile.Sections[Integer(ARecordHandle)];
end;

function TUserDataSource.AppendRecord: TcxDataRecordHandle;
begin
 with DataIniFile do
 begin
   InsertSection(-1 , '...', True);
   Modified := True;
   Result := TcxDataRecordHandle(Sections.Count - 1);
 end;
 DataChanged;
end;

function TUserDataSource.InsertRecord(
  ARecordHandle: TcxDataRecordHandle): TcxDataRecordHandle;
begin
 with DataIniFile do
 begin
   InsertSection(Integer(ARecordHandle), '...');
   Modified := True;
   Result := ARecordHandle;
 end;
 DataChanged;
end;

procedure TUserDataSource.SetValue(ARecordHandle: TcxDataRecordHandle;
  AItemHandle: TcxDataItemHandle; const AValue: Variant);
begin
  with DataIniFile do
  begin
    ChangeSectionName(Integer(ARecordHandle), VarAsType(AValue, varOLEStr));
    Modified := True;
  end;
end;

{ TUserDetailDataSource }

function TUserDetailDataSource.AppendRecord: TcxDataRecordHandle;
var
  AStrings: TStrings;
begin
  with MasterDataSource.DataIniFile do
  begin
    AStrings := TStrings(Sections.Objects[GetMasterRecordIndex]);
    Result := TcxDataRecordHandle(AStrings.Add(''));
    Modified := True;
  end;
  DataChanged;
end;

constructor TUserDetailDataSource.Create(ADataSource: TUserDataSource);
begin
  inherited Create;
  FDataSource := ADataSource;
end;

procedure TUserDetailDataSource.DeleteRecord(
  ARecordHandle: TcxDataRecordHandle);
var
  AStrings: TStrings;
begin
  with MasterDataSource.DataIniFile do
  begin
    AStrings := TStringList(Sections.Objects[GetMasterRecordIndex]);
    AStrings.Delete(Integer(ARecordHandle));
    Modified := True;
  end;
  DataChanged;
end;

function TUserDetailDataSource.GetMasterRecordIndex: Integer;
begin
  Result := DataController.GetMasterRecordIndex;
end;

function TUserDetailDataSource.GetRecordCount: Integer;
begin
  Result := 0;
  if GetMasterRecordIndex >= 0 then
    Result := TStrings(MasterDataSource.DataIniFile.Sections.Objects[GetMasterRecordIndex]).Count
end;

function TUserDetailDataSource.GetValue(ARecordHandle: TcxDataRecordHandle;
  AItemHandle: TcxDataItemHandle): Variant;
var
  AStrings: TStrings;
  AColumnId: Integer;
begin
  AColumnId := GetDefaultItemID(Integer(AItemHandle));
  AStrings := TStrings(MasterDataSource.DataIniFile.Sections.Objects[GetMasterRecordIndex]);
  if AColumnId = 0 then
    Result := AStrings.Names[Integer(ARecordHandle)]
  else
    Result := AStrings.Values[AStrings.Names[Integer(ARecordHandle)]];
end;

function TUserDetailDataSource.InsertRecord(
  ARecordHandle: TcxDataRecordHandle): TcxDataRecordHandle;
var
  AStrings: TStrings;
begin
  with MasterDataSource.DataIniFile do
  begin
    AStrings := TStrings(Sections.Objects[GetMasterRecordIndex]);
    AStrings.Insert(Integer(ARecordHandle), '');
    Modified := True;
    Result := ARecordHandle;
  end;
  DataChanged;
end;

procedure TUserDetailDataSource.SetValue(
  ARecordHandle: TcxDataRecordHandle; AItemHandle: TcxDataItemHandle;
  const AValue: Variant);
var
  AStrings: TStrings;
  AColumnId: Integer;
  S1, S2: string;
begin
  AColumnId := GetDefaultItemID(Integer(AItemHandle));
  with MasterDataSource.DataIniFile do
  begin
    AStrings := TStrings(Sections.Objects[GetMasterRecordIndex]);
    if AColumnId = 0 then  // set name
    begin
      if VarIsNull(AValue) then
        S1 := ''
      else S1 := AValue;
      S2 := AStrings.Values[AStrings.Names[Integer(ARecordHandle)]]
    end
    else // set value
    begin
      S1 := AStrings.Names[Integer(ARecordHandle)];
      if VarIsNull(AValue) then
        S2 := ''
      else S2 := AValue;
    end;
    AStrings.Strings[Integer(ARecordHandle)]:= Format('%S=%S', [S1,S2]);
    Modified := True;
   end;
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -