如何在应用于数据库之前本地更新复选框状态?

问题描述 投票:0回答:1

德尔福10.4。 Firebird 数据库表有一个布尔字段

PickedUp
。数据集是一个
TFDQuery
组件。

TDBGrid
中有文件记录。在表单上我放置了一个
TDBCheckBox
组件。
TDBCheckBox
PickedUp
TFDQuery
字段相关联。

我的目标是,当我选中

TDBGrid
中的复选框时,状态更改本地存储在数组中,当我单击
Apply
按钮时,选中文档的所有状态更改都保存在
PickedUp
中表的字段。

问题是,当我单击复选框时,它会“内部”切换,但我看不到它,我看不到哪些复选框状态已更改,哪些未更改。

点击

Apply
按钮并刷新数据集后,我看到CheckBoxes的状态已经成功更改,但是如何在应用之前看到更改后的状态?

我创建了一个数组来存储本地更改,单击

Apply
按钮后,我将这些更改反映到数据库中。

OnCreate
事件形式:

dbcheckbox1.DataSource := dsOutBound;
dbcheckbox1.DataField := 'PickedUp';
dbcheckbox1.Visible := False;
dbcheckbox1.Color := dbgOutBound.Color;
dbcheckbox1.Caption := '';
dbcheckbox1.Parent := dbgOutBound; 

其他活动:

type
  TDocumentInfo = record
    DocumentID: Integer;
    PickedUp: Boolean;
  end;
    
var
  DocumentsToUpdate: TArray<TDocumentInfo>;
    
procedure Tform1.dbgrid1CellClick(Column: TColumn);
var
  DocumentID: Integer;
  PickedUp: Boolean;
begin
  if Column.Field.DataType = ftBoolean then
  begin
    // Store the changes locally without immediately updating the database
    DocumentID := dbgrid1.DataSource.DataSet.FieldByName('DOCUMENTID').AsInteger;
    PickedUp := not Column.Field.AsBoolean; // Toggle the value
    
    SetLength(DocumentsToUpdate, Length(DocumentsToUpdate) + 1);
    DocumentsToUpdate[High(DocumentsToUpdate)].DocumentID := DocumentID;
    DocumentsToUpdate[High(DocumentsToUpdate)].PickedUp := PickedUp;
    
    // Update the checkbox state locally
    Column.Field.AsBoolean := PickedUp;
  end;
end;
    
procedure Tform1.UpdateCheckedDocumentsPickedUp;
var
  i: Integer;
  Bookmark: TBookmark;
  DocumentID: Integer;
  PickedUp: Boolean;
begin
  if Length(DocumentsToUpdate) = 0 then
    Exit;
    
  Bookmark := dbgrid1.DataSource.DataSet.GetBookmark;
  dbgrid1.DataSource.DataSet.DisableControls;
  try
    for i := Low(DocumentsToUpdate) to High(DocumentsToUpdate) do
    begin
      DocumentID := DocumentsToUpdate[i].DocumentID;
      PickedUp := DocumentsToUpdate[i].PickedUp;
    
      // Locate the record by DocumentID
      if dbgrid1.DataSource.DataSet.Locate('DOCUMENTID', DocumentID, []) then
      begin
        // Apply the change only for the checked records
        dbgrid1.DataSource.DataSet.Edit;
        dbgrid1.DataSource.DataSet.FieldByName('PICKEDUP').AsBoolean := PickedUp;
        dbgrid1.DataSource.DataSet.Post;
      end;
    end;
  finally
    dbgrid1.DataSource.DataSet.GotoBookmark(Bookmark);
    dbgrid1.DataSource.DataSet.FreeBookmark(Bookmark);
    dbgrid1.DataSource.DataSet.EnableControls;
  end;
    
  // Clear the local changes after applying them
  SetLength(DocumentsToUpdate, 0);
end;
    
procedure Tform1.Button1Click(Sender: TObject);
begin
  UpdateCheckedDocumentsPickedUp;
end;
    
procedure Tform1.dbgrid1DrawColumnCell(Sender: TObject;
  const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState);
const
  CtrlState: array[Boolean] of integer = (DFCS_BUTTONCHECK, DFCS_BUTTONCHECK or DFCS_CHECKED) ;
  IsChecked : array[Boolean] of Integer =
     (DFCS_BUTTONCHECK, DFCS_BUTTONCHECK or DFCS_CHECKED);
begin
  if Column.FieldName = 'PICKEDUP' then
    if Column.Field.AsBoolean then
      DrawGridCheckBox(dbgrid1.Canvas, Rect, true)
    else
      DrawGridCheckBox(dbgrid1.Canvas, Rect, false);
end;
    
procedure Tform1.DrawGridCheckBox(Canvas: TCanvas; Rect: TRect; Checked: boolean);
var
  DrawFlags: Integer;
begin
  Canvas.TextRect(Rect, Rect.Left + 1, Rect.Top + 1, ' ');
  DrawFrameControl(Canvas.Handle, Rect, DFC_BUTTON, DFCS_BUTTONPUSH or DFCS_ADJUSTRECT);
  DrawFlags := DFCS_BUTTONCHECK or DFCS_ADJUSTRECT;// DFCS_BUTTONCHECK
  if Checked then
    DrawFlags := DrawFlags or DFCS_CHECKED;
  DrawFrameControl(Canvas.Handle, Rect, DFC_BUTTON, DrawFlags);
end;
delphi firedac delphi-10.4-sydney
1个回答
0
投票

您可以致电

TDataSet.UpdateRecord
。文档说:

确保数据感知控件和详细数据集反映记录 更新。

© www.soinside.com 2019 - 2024. All rights reserved.