2017年9月7日 星期四

wwDBGrid拖移資料列(Drop Record)

F_pnlDragRecord:TPanel;
F_DragImage:TImage
F_DragImage.Parant := F_pnlDragRecord;

//----------------
//MouseDown
//----------------
procedure TfrmBaseForm.wwDBGrid1MouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  pt: TPoint;
  gc: TGridCoord;
  idx, odx: integer;
  vAry: TStrings;
  vRfd: string;
begin
  gc := TwwDBGrid(Sender).MouseCoord(x, y);
  //當游標點選到第一個行, 才允許操作拖移功能
  if Assigned(TwwDBGrid(Sender).DataSource) and (TwwDBGrid(Sender).DataSource.DataSet.Active)
    and (TwwDBGrid(Sender).DataSource.DataSet.RecordCount>1) and (gc.X=0) and (gc.Y>0) and (Button=mbLeft) then
  begin
    //記錄來源列的列數, ps.Scroll的捲動,MouseCoord在wwDBGrid取得的格位, 左上角永遠是Cell[0,0]
    F_Drag_Row := gc.Y;
    //取消所有的排序功能
    if TwwDBGrid(Sender).DataSource.DataSet is TTCClientDataSet then
    begin
      TTCClientDataSet(TwwDBGrid(Sender).DataSource.DataSet).IndexName := '';
      TTCClientDataSet(TwwDBGrid(Sender).DataSource.DataSet).IndexDefs.Clear;
      TTCClientDataSet(TwwDBGrid(Sender).DataSource.DataSet).IndexFieldNames := '';
    end
    else if TwwDBGrid(Sender).DataSource.DataSet is TCustomADODataSet then
    begin
      TCustomADODataSet(TwwDBGrid(Sender).DataSource.DataSet).IndexName := '';
      TCustomADODataSet(TwwDBGrid(Sender).DataSource.DataSet).Sort := '';
    end;
    TwwDBGrid(Sender).BeginDrag(True);
  end;
end;

//------------
//DragOver
//------------
procedure TfrmBaseForm.wwDBGrid1DragOver(Sender, Source: TObject; X,
  Y: Integer; State: TDragState; var Accept: Boolean);
var ptPoint:TPoint;
  gcCell:TGridCoord;
  rtRect:TRect;
  i, iWidth:Integer;
begin
  inherited;
  gcCell := TwwDBGrid(sender).MouseCoord(X, Y);
  Accept := (Source is TwwDBGrid) and (Sender=Source) and
    (gcCell.Y > 0);
  //
  if (State=dsDragLeave) or (not Accept) then
    Exit;
  //
  if (State=dsDragMove) and (not F_pnlDragRecord.Visible) then
  begin
    F_pnlDragRecord.Left := TwwDBGrid(sender).ClientOrigin.X+TwwDBGrid(Sender).ColWidths[0]+1;
    F_pnlDragRecord.Height := TwwDBGrid(Sender).RowHeights[1];
    //寬度控制
    iWidth := 0;
    for i:=0 to TwwDBGrid(Sender).FieldCount-1 do
    begin
      if iWidth + TwwDBGrid(Sender).ColWidths[i] > TwwDBGrid(Sender).Width then
        Break;
      iWidth := iWidth + TwwDBGrid(Sender).ColWidths[i];
    end;
    F_pnlDragRecord.Width := iWidth;
    //畫資料列
    gcCell := TwwDBGrid(sender).MouseCoord(X, Y);
    rtRect := TwwDBGrid(Sender).CellRect(1, gcCell.Y);
    F_DragImage.Picture := nil;
    F_DragImage.Canvas.CopyRect(
      Rect(0, 0, F_DragImage.Width,F_DragImage.Height),
      TwwDBGrid(sender).Canvas,
      Rect(rtRect.Left, rtRect.Top, rtRect.Left+F_DragImage.Width, rtRect.Top+F_DragImage.Height)
    );
    //
    F_pnlDragRecord.Visible := True;
    F_pnlDragRecord.BringToFront;
  end;
  //Top座標控制
  gcCell := TwwDBGrid(sender).MouseCoord(X, Y);
  rtRect := TwwDBGrid(Sender).CellRect(1, gcCell.Y);
  ptPoint := TwwDBGrid(sender).ClientToScreen(rtRect.TopLeft);
  ptPoint := Self.ScreenToClient(ptPoint);

  F_pnlDragRecord.Left := ptPoint.X;
  F_pnlDragRecord.Top := ptPoint.Y;
end;

//------------
//StartDrag
//------------
procedure TfrmBaseForm.wwDBGrid1StartDrag(Sender: TObject;
  var DragObject: TDragObject);
var i:Integer;
  cdsDataset:TDataset;
begin
  inherited;
  //
  if not Assigned(F_pnlDragRecord) then
  begin
    F_pnlDragRecord := TPanel.Create(Self);
    F_pnlDragRecord.Parent := Self;
    F_pnlDragRecord.Enabled := False;
    F_pnlDragRecord.Visible := False;
    F_DragImage := TImage.Create(Self);
    F_DragImage.Parent := F_pnlDragRecord;
    F_DragImage.Align := alClient;
    F_DragImage.Enabled := False;
  end;
  //記錄原始列的資料
  cdsDataset := TwwDBGrid(Sender).DataSource.DataSet;
  VarClear(F_Drag_Values);
  F_Drag_Values := VarArrayCreate([0, cdsDataset.FieldCount-1], varVariant);
  for i:=0 to cdsDataset.FieldCount-1 do
  begin
    F_Drag_Values[i] := cdsDataset.Fields[i].AsString;
  end;
end;

//------------
//DragDrop
//------------
procedure TfrmBaseForm.wwDBGrid1DragDrop(Sender, Source: TObject; X,
  Y: Integer);
var cdsDataset:TDataset;
  gcCell:TGridCoord;
  iTargetRecno:Integer;
  procedure pr_AssignRecordData;
  var i:Integer;
  begin
    for i:=0 to cdsDataset.FieldCount-1 do
    begin
      if (not cdsDataset.Fields[i].ReadOnly) and (cdsDataset.Fields[i].FieldKind=fkData) then
      begin
        if cdsDataset.Fields[i] is TWideStringField then
          cdsDataset.Fields[i].Value := VarToWideStr(F_Drag_Values[i]) //WideString
        else
          cdsDataset.Fields[i].AsString := VarToStr(F_Drag_Values[i]); //選用通用的資料型態寫入
      end;
    end;
  end;
begin
  inherited;
  cdsDataset := TwwDBGrid(Sender).DataSource.DataSet;
  gcCell := TwwDBGrid(Sender).MouseCoord(X, Y); //Scroll的捲動,MouseCoord在wwDBGrid取得的格位, 左上角永遠是Cell[0,0]
  iTargetRecno := cdsDataset.RecNo + (gcCell.Y - F_Drag_Row); //Dataset資料列 + 列數差

  if Assigned(F_pnlDragRecord) and (F_pnlDragRecord.Visible) then
    F_pnlDragRecord.Visible := False;

  if (gcCell.Y=F_Drag_Row) or (gcCell.Y<=0) then
    Exit;

  //刪除來源列
  cdsDataset.Delete;

  //
  if iTargetRecno > cdsDataset.RecordCount then
  begin
    cdsDataset.Append;
    pr_AssignRecordData;
    cdsDataset.Post;
  end
  else
  begin
    cdsDataset.RecNo := iTargetRecno;
    cdsDataset.Insert;
    pr_AssignRecordData;
    cdsDataset.Post;
  end;

  if Assigned(F_pnlDragRecord) then
    F_pnlDragRecord.Visible := False;
end;

//-----------
//EndDrag
//-----------
procedure TfrmBaseForm.wwDBGrid1EndDrag(Sender, Target: TObject; X,
  Y: Integer);
begin
  inherited;
  if Assigned(F_pnlDragRecord) then
    F_pnlDragRecord.Visible := False;
end;

沒有留言:

張貼留言