Konuyu Oyla:
  • Derecelendirme: 5/5 - 1 oy
  • 1
  • 2
  • 3
  • 4
  • 5
[ÇÖZÜLDÜ-SOLVED] StringGrid Satır Taşıma(Move Row)
#1
Merhaba,
Delphi bileşeni olan StringGrid içine doldurduğum verilerde satır taşıma yapmak istiyorum. (Delphi 7, TStringGrid)
  • Aşağıda resimde görüldüğü gibi bilgileri gride dolduruyorum.
  • Grid ayarlarını da yapıyorum.
  • Taşıma ile ilgili bir sıkıntı yok gayet güzel taşıyor.
type
 TStringGridX = class(TCustomGrid)
 public
   property GridState: TGridState read FGridState write FGridState;
 end;
   
sGrid.FixedCols := 1;
sGrid.FixedRows := 1;
sGrid.Options := sGrid.Options + [goRowMoving];

procedure TFormX.sGridMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  gc: TGridCoord;
begin
  if Sender is TStringGrid then
  begin
    if TStringGridX(Sender).GridState in [gsRowMoving] then
    begin
      TStringGrid(Sender).MouseToCell(X, Y, gc.X, gc.Y);
      //seçili satırın numarasını al
      FFromIndex := gc.Y;
    end;
  end;
end;

procedure TFormX.sGridMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
 gc: TGridCoord;
begin
  if Sender is TStringGrid then
  begin
    if TStringGridX(Sender).GridState in [gsRowMoving] then
    begin
      TStringGrid(Sender).MouseToCell(X, Y, gc.X, gc.Y);
      FToIndex := gc.Y;
    end;
  end;
end;

procedure TFormX.sGridMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
var
   gc: TGridCoord;
begin
  if Sender is TStringGrid then
  begin
    if TStringGridX(Sender).GridState in [gsRowMoving] then
    begin
      TStringGrid(Sender).MouseToCell(X, Y, gc.X, gc.Y);
      //burada hangi satırlarda olduğumu biliyorum.
      Caption := IntToStr(gc.X) + ':' + IntToStr(gc.Y);
    end;
  end;
end;

procedure TFormX.sGridRowMoved(Sender: TObject; FromIndex, ToIndex: Integer);
begin
  //ayrıca burada hangi satırdan hangi satıra taşıma işlemi yapıldığı da yazıyor.
  //ben bu taşıma işlemini ilk satırı taşımak için mouse ile tuttuğumda hangi satırlara taşınabileceğini buluyorum. İstediğim satır değilse bu işlemi nasıl iptal ederim.
end;

Fakat ben bu taşıma işlemi ile ilgili satır sınırları(Üst Satır, Alt Satır) belirlemek istiyorum.
Ürünler Ana ürün(Paket ürün) altındaki alt ürünler mantığında tutuluyor. Renklerden de görüldüğü gibi asıl ürünler renkli satırlar.

Aşağıdaki resimden örnekle,
Örnek 1-) 10. satırdaki A9 kodunu alt ürün olduğu için 2 ve 15. satırlar arasından başka yere taşınmasına izin vermemem gerekiyor.
Örnek 2-) 20. satırdaki F kodunu ana ürün(paket ürün) olduğu için 1, 16, 23, 27 numaralı satırlara taşınabilir. Ayrıca bu F kodu ile birlikte altına F1 ve F2 satırlarını da taşıyacağım. Bununla ilgili taşıma işlemi başladığında taşımanın yapılabileceği satırlarını buluyorum. 

Fakat limit kısmını tam olarak yapamadım.
Forumlarda bir yerde Windows.ClipCursor kullanılmış fakat bu işimi görmüyor. Gridin MouseMove eventinde hangi satırda olduğumu da yakalıyorum. Fakat burada satır taşıma işlemini nasıl sınırlayacağım bilemedim.

Karışık bir durum gibi görünse de asıl istediğim.
Sadece satır taşıma işini nasıl iptal ederim?
Taşıma işleminde sadece benim istediğim satırların üzerinde gezmesini nasıl sağlarım?

Şimdiden teşekkürler..
PostgreSQL - Linux - Delphi, Poliüretan
WWW
Cevapla
#2
Drag & Drop olayları işinize yarayacak gibi görünüyor.
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#3
Başlarken source alıp, Bırakma esnasında cursorun üzerinde bulunduğu nesneyi alarak kontroller yapılabilir gibi geliyor.
Yalnızım ama bir kente yürüyen ordu gibiyim, edebiyattan kaçınmalıyım..
Cevapla
#4
(17-03-2020, Saat: 18:15)Tuğrul HELVACI Adlı Kullanıcıdan Alıntı: Drag & Drop olayları işinize yarayacak gibi görünüyor.

DraMode := dmAutomatic
 yaptığımda fixed row üzerinden yaptığım satır taşıma iptal oluyor.

TMS AdvStringGrid event listesindeki RowMoving eventinden istediğim işlemi çok güzel bir şekilde yapabiliyorum.
procedure TForm1.grd2RowMoving(Sender: TObject; ARow: Integer;
  var Allow: Boolean);
begin
  Allow := ARow in [1,3,9];//taşıma işlemine başladıktan sonra taşıma yapılacak satır sadece 1,3,9 numaralı satırlara taşınsın şeklinde belirtilebiliyor.
end;

StringGrid sınıfının base sınıfı olan CustomGrid içindeki MouseMove ve WMTimer olaylarını veya MoveAndScroll olayını istediğim gibi değiştirmem gerekiyor.

TCustomGrid = class(TCustomControl)
...
....
.....
private
  ...
  procedure WMTimer(var Msg: TWMTimer); message WM_TIMER;
protected
  ...
  procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
end;

implementation

procedure TCustomGrid.MouseMove(Shift: TShiftState; X, Y: Integer);
var
 DrawInfo: TGridDrawInfo;
 CellHit: TGridCoord;
begin
 CalcDrawInfo(DrawInfo);
 case FGridState of
   gsSelecting, gsColMoving, gsRowMoving:
     begin
       CellHit := CalcCoordFromPoint(X, Y, DrawInfo);
       if (CellHit.X >= FixedCols) and (CellHit.Y >= FixedRows) and
         (CellHit.X <= DrawInfo.Horz.LastFullVisibleCell+1) and
         (CellHit.Y <= DrawInfo.Vert.LastFullVisibleCell+1) then
         case FGridState of
           gsSelecting:
             if ((CellHit.X <> FAnchor.X) or (CellHit.Y <> FAnchor.Y)) then
               MoveAnchor(CellHit);
           gsColMoving:
             MoveAndScroll(X, CellHit.X, DrawInfo, DrawInfo.Horz, SB_HORZ, Point(X,Y));
           gsRowMoving:
             //buradaki CellHit.Y mouse ile üzerinde bulunduğum satır numarası bu satır numarası benim istediğim satırlar içindeyse bu işlemi yapmama izin verecek
             MoveAndScroll(Y, CellHit.Y, DrawInfo, DrawInfo.Vert, SB_VERT, Point(X,Y));
         end;
     end;
   gsRowSizing, gsColSizing:
     begin
       DrawSizingLine(DrawInfo); { XOR it out }
       if FGridState = gsRowSizing then
         FSizingPos := Y + FSizingOfs else
         FSizingPos := X + FSizingOfs;
       DrawSizingLine(DrawInfo); { XOR it back in }
     end;
 end;
 inherited MouseMove(Shift, X, Y);
end;

procedure TCustomGrid.WMTimer(var Msg: TWMTimer);
var
 Point: TPoint;
 DrawInfo: TGridDrawInfo;
 ScrollDirection: TGridScrollDirection;
 CellHit: TGridCoord;
 LeftSide: Integer;
 RightSide: Integer;
begin
 if not (FGridState in [gsSelecting, gsRowMoving, gsColMoving]) then Exit;
 GetCursorPos(Point);
 Point := ScreenToClient(Point);
 CalcDrawInfo(DrawInfo);
 ScrollDirection := [];
 with DrawInfo do
 begin
   CellHit := CalcCoordFromPoint(Point.X, Point.Y, DrawInfo);
   case FGridState of
     gsColMoving:
       MoveAndScroll(Point.X, CellHit.X, DrawInfo, Horz, SB_HORZ, Point);
     gsRowMoving:
       //buradaki CellHit.Y mouse ile üzerinde bulunduğum satır numarası bu satır numarası benim istediğim satırlar içindeyse bu işlemi yapmama izin verecek
       MoveAndScroll(Point.Y, CellHit.Y, DrawInfo, Vert, SB_VERT, Point);
     gsSelecting:
     begin
       if not UseRightToLeftAlignment then
       begin
         if Point.X < Horz.FixedBoundary then Include(ScrollDirection, sdLeft)
         else if Point.X > Horz.FullVisBoundary then Include(ScrollDirection, sdRight);
       end
       else
       begin
         LeftSide := ClientWidth - Horz.FullVisBoundary;
         RightSide := ClientWidth - Horz.FixedBoundary;
         if Point.X < LeftSide then Include(ScrollDirection, sdRight)
         else if Point.X > RightSide then Include(ScrollDirection, sdLeft);
       end;
       if Point.Y < Vert.FixedBoundary then Include(ScrollDirection, sdUp)
       else if Point.Y > Vert.FullVisBoundary then Include(ScrollDirection, sdDown);
       if ScrollDirection <> [] then  TimedScroll(ScrollDirection);
     end;
   end;
 end;
end;

//veya aşağıdaki kısımda bu işlemi yapmalıyım sonuçta ikiside aynı procedure geliyor.
procedure TCustomGrid.MoveAndScroll(Mouse, CellHit: Integer;
 var DrawInfo: TGridDrawInfo; var Axis: TGridAxisDrawInfo;
 ScrollBar: Integer; const MousePt: TPoint);
begin
 if UseRightToLeftAlignment and (ScrollBar = SB_HORZ) then
   Mouse := ClientWidth - Mouse;
 if (CellHit <> FMovePos) and
   not((FMovePos = Axis.FixedCellCount) and (Mouse < Axis.FixedBoundary)) and
   not((FMovePos = Axis.GridCellCount-1) and (Mouse > Axis.GridBoundary)) then
 begin
   DrawMove;   // hide the drag line
   if (Mouse < Axis.FixedBoundary) then
   begin
     if (FMovePos > Axis.FixedCellCount) then
     begin
       ModifyScrollbar(ScrollBar, SB_LINEUP, 0, False);
       Update;
       CalcDrawInfo(DrawInfo);    // this changes contents of Axis var
     end;
     CellHit := Axis.FirstGridCell;
   end
   else if (Mouse >= Axis.FullVisBoundary) then
   begin
     if (FMovePos = Axis.LastFullVisibleCell) and
       (FMovePos < Axis.GridCellCount -1) then
     begin
       ModifyScrollBar(Scrollbar, SB_LINEDOWN, 0, False);
       Update;
       CalcDrawInfo(DrawInfo);    // this changes contents of Axis var
     end;
     CellHit := Axis.LastFullVisibleCell;
   end
   else if CellHit < 0 then CellHit := FMovePos;
   if ((FGridState = gsColMoving) and CheckColumnDrag(FMoveIndex, CellHit, MousePt))
     or ((FGridState = gsRowMoving) and CheckRowDrag(FMoveIndex, CellHit, MousePt)) then
     FMovePos := CellHit;
   DrawMove;
 end;
end;
PostgreSQL - Linux - Delphi, Poliüretan
WWW
Cevapla
#5
Farklı bir şekilde yapacağım. Kullanıcının herhangi bir satıra sürükleme hakkı olacak ki zaten var ve ben bunu kontrol edemiyorum.

Fakat mouseup olayında(taşıma bitimi) taşıma yapılan satırın nerelere gidebileceğini mouse down olayında aldığım için sınır dışında ise manuel kod ile kendim sınırlar içine taşıyacağım. Böylece nispeten istediğim işlemi yapmış olacağım.
PostgreSQL - Linux - Delphi, Poliüretan
WWW
Cevapla
#6
Sanırım sıkıntının ne olduğunu tam olarak anlayamadık. Aşağıdaki gibi bir kod işinize yaramıyor mu ?

procedure TForm4.StringGrid1DragOver(Sender, Source: TObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
var
 ACol, ARow : Integer;
begin
 StringGrid1.MouseToCell(X, Y, ACol, ARow);

 Accept := (ACol = 2) and (ARow = 3);
end;

Yukarıdaki kod için TStringGrid'in DragMode property'sinin değerini dmAutomatic yaptık ve sadece 2nci kolon 3üncü satıra sürükleme yapabilirsin dedik.
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#7
@Tuğrul HELVACI  hocam ben derdimi tam olarak ifade edememiş olabilirim.

Şimdi StringGrid Options içinde goRowMoving özelliği var. Bu Özellik aktif edildiğinde ve FixedCols > 0 olarak belirlendiğinde (ben 1 kullandım) Fixed kolon üzerinden satırı yakalayıp taşına işlemini Drag & Drop a gerek kalmadan (DragMode=dmManual bırakıyorum) Satır içinde Object doldurulmuşsa (sGrid.Objects[ACol, ARow] := TObjectX) bununla birlikte taşıma yapabiliyoruz. Ayrıca bu işlemi yaparken de hangi satıra taşıma yapıldığı da boyama yaparak gösteriliyor. Böylece ek bir efor harcamadan StringGrid içinde taşıma işlemi gerçekleşmiş oluyor.

Ayrıca aşağıda da video olarak bir kayıt aldım.


PostgreSQL - Linux - Delphi, Poliüretan
WWW
Cevapla
#8
Çözümü paylaşıyorum. Farklı bir şekilde çözüme ulaştım.
NOT: Kendi kodumu formda yazmak adına uygun hale getirmeye çalıştım yazım hataları eksikleri olabilir.
Öncelikle aşağıdaki tipleri, private global değişkenleri ve stringgrid üzerindeki eventleri tanımlıyoruz. Ayrıca List içinde sıralama yapmak için CompareSiraNos procedure tanımlıyoruz.
  • Ana mantık ilk MouseDown olayın seçtiğimiz satırın tipi yani ana, alt veya bağımsız ürün olduğunu buluyoruz. Aynı işlem içinde bu satırı tipine göre seçilen satırın hangi satırlara taşıma yapabileceğini array içine dolduruyoruz.
  • MouseMove olayında da taşıma sırasında mouse koordinatı grid dışına çıkarsa taşıma işlemini engelliyoruz.
  • MouseUp olayında da taşımayı bıraktığımız satır bizin taşıma yapabileceğimiz satır ise taşımayı yapıyoruz aksi durumda taşıma her durumda gerçekleşiyor ve bizde bu taşımayı geri alıyoruz. Buna ilave olarak taşıma yapılan satır tipi Ana Ürün ise alt ürünleri de birlikte taşıma yapıyoruz. Sonrasında SiraNo bilgisini güncelleyip Listeyi sort ediyor ve gridi yeniden dolduruyoruz.



type
  TSatirTipi = (stAna, stAlt, stBagimsiz);
  TTasimaYonu = (tyAsagi, tyYukari);
  TStringGridX = class(TCustomGrid);

  TFormX = (TForm)
  ...
  private
    FFromIndex: Integer;
    FFromUrunID: Integer;
    FFromSatirTipi: TSatirTipi;
    FTasimaYapilabilirSatirlar: Array Of SmallInt;
  ...
  published
    procedure StringGridMouseMove(Sender: TObject; Shift: TShiftState;
      X: Integer; Y: Integer); override;
    procedure StringGridMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X: Integer; Y: Integer); override;
    procedure StringGridMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X: Integer; Y: Integer); override;
end;

implementation
...
function CompareSiraNos(Item1, Item2: Pointer): Integer;
begin
  Result := CompareValue(TXList(Item1).SiraNo, TXList(Item2).SiraNo);
end;

procedure TFormX.FormCreate(Sender: TObject);
begin
  inherited;
  ...
 StringGrid.FixedCols := 1;
 StringGrid.Options := StringGrid.Options + [goRowMoving];
end;

Destructor TFormX.Destroy;
begin
  StringGrid.FixedCols := 0;
  StringGrid.Options := StringGrid.Options - [goRowMoving];
  ...
  inherited;
end;

procedure TFormX.fillGrid();
var
  ...
begin
  StringGrid.Perform(WM_SETREDRAW, 0, 0);
  try
    OldRow  := StringGrid.Row;
    TopRow  := StringGrid.TopRow;
    n1 := 0;
    ...
    ResetGrid();
    ...
    for nRow := 0 to xList.Count - 1 do
    begin
      if nRow > 0 then
      begin
        StringGrid.RowCount := StringGrid.RowCount + 1;
        StringGrid.Row := StringGrid.Row + 1;
      end;
      Inc(n1);
      TXObject(xList[nRow]).SiraNo := n1;

      StringGrid.Cells[COLUMN_OBJECT, StringGrid.Row] := IntToStr(n1);
      StringGrid.Objects[COLUMN_OBJECT, StringGrid.Row] := TXObject(xList[nRow]);
      ...
      ...
      end;
    end;

    if StringGrid.RowCount > TopRow then
      StringGrid.TopRow  := TopRow;
    if StringGrid.RowCount > OldRow then
      StringGrid.Row     := OldRow;
  finally
    StringGrid.Perform(WM_SETREDRAW, 1, 0);
    StringGrid.Invalidate;
  end;
end;

procedure TFormX.StringGridMouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  gc: TGridCoord;
  ARow: Integer;
  n1, i, nLen: Integer;
begin
  if Sender is TStringgrid then
  begin
    if  (TStringGridX(Sender).FGridState = gsRowMoving) then
    begin
      gc := TStringGrid(Sender).MouseCoord(X, Y);
      ARow := gc.Y;
      FFromIndex := ARow;
      if Assigned(TStringGrid(Sender).Objects[COLUMN_OBJECT, ARow]) then
      begin
        //list kadar array uzunluğunu belirtiyoruz.
        SetLength(FTasimaYapilabilirSatirlar, xList.Count);
        nLen := Length(FTasimaYapilabilirSatirlar);
        //array içini temizliyoruz
        for n1 := 0 to nLen-1 do
          FTasimaYapilabilirSatirlar[n1] := 0;

        i := 0;
        //ana ürün ise
        if  (TXObject(TStringGrid(Sender).Objects[COLUMN_OBJECT, ARow]).IsAnaUrun)
        and (TXObject(TStringGrid(Sender).Objects[COLUMN_OBJECT, ARow]).AnaUrunId <> 0)
        and (TXObject(TStringGrid(Sender).Objects[COLUMN_OBJECT, ARow]).ReferenceAnaUrunId <> 0)
        then
        begin
          FFromSatirTipi := stAna;
          FFromUrunID := TXObject(TStringGrid(Sender).Objects[COLUMN_OBJECT, ARow]).AnaUrunId;

          for n1 := 1 to TStringGrid(Sender).RowCount-1 do
          begin
            if Assigned(TStringGrid(Sender).Objects[COLUMN_OBJECT, n1]) then
            begin
              //seçili ana ürün haricindeki ana ürünlerin bulunduğu satırlara taşıma yapılabilir
              if  (TXObject(TStringGrid(Sender).Objects[COLUMN_OBJECT, n1]).AnaUrunId <> 0)
              and (TXObject(TStringGrid(Sender).Objects[COLUMN_OBJECT, n1]).AnaUrunId <> FFromUrunID)
              and (n1 <> ARow)
              then
              begin
                FTasimaYapilabilirSatirlar[i] := n1;
                Inc(i);
              end
              else
              //veya bağımsız ürünlerin olduğu satırlara taşıma yapılabilir
              if  (TXObject(TStringGrid(Sender).Objects[COLUMN_OBJECT, n1]).AnaUrunId = 0)
              and (TXObject(TStringGrid(Sender).Objects[COLUMN_OBJECT, n1]).ReferenceAnaUrunId = 0)
              and (n1 <> ARow)
              then
              begin
                FTasimaYapilabilirSatirlar[i] := n1;
                Inc(i);
              end
            end;
          end;
          //ana ürün her durumda en alt satıra taşıma yapılabilir
          FTasimaYapilabilirSatirlar[i] := TStringGrid(Sender).RowCount-1;
        end
        else
        if  (not TXObject(TStringGrid(Sender).Objects[COLUMN_OBJECT, ARow]).IsAnaUrun)
        and (TXObject(TStringGrid(Sender).Objects[COLUMN_OBJECT, ARow]).AnaUrunId = 0)
        and (TXObject(TStringGrid(Sender).Objects[COLUMN_OBJECT, ARow]).ReferenceAnaUrunId = 0)
        then
        begin
          FFromSatirTipi := stBagimsiz;
          FFromUrunID := TXObject(TStringGrid(Sender).Objects[COLUMN_OBJECT, ARow]).AnaUrunId;

          for n1 := 1 to TStringGrid(Sender).RowCount-1 do
          begin
            if Assigned(TStringGrid(Sender).Objects[COLUMN_OBJECT, n1]) then
            begin
              //seçili ürün haricindeki ana ürünlerin bulunduğu satırlara taşıma yapılabilir
              if  (TXObject(TStringGrid(Sender).Objects[COLUMN_OBJECT, n1]).AnaUrunId <> 0)
              and (TXObject(TStringGrid(Sender).Objects[COLUMN_OBJECT, n1]).AnaUrunId <> FFromUrunID)
              and (n1 <> ARow)
              then
              begin
                FTasimaYapilabilirSatirlar[i] := n1;
                Inc(i);
              end
              else
              //veya bağımsız ürünlerin olduğu satırlara taşıma yapılabilir
              if  (TXObject(TStringGrid(Sender).Objects[COLUMN_OBJECT, n1]).AnaUrunId = 0)
              and (TXObject(TStringGrid(Sender).Objects[COLUMN_OBJECT, n1]).ReferenceAnaUrunId = 0)
              and (n1 <> ARow)
              then
              begin
                FTasimaYapilabilirSatirlar[i] := n1;
                Inc(i);
              end
            end;
          end;
          //bağımsız ürün en alt satıra taşıma yapılabilir
          FTasimaYapilabilirSatirlar[i] := TStringGrid(Sender).RowCount-1;
        end
        else
        if  (not TXObject(TStringGrid(Sender).Objects[COLUMN_OBJECT, ARow]).IsAnaUrun)
        and (TXObject(TStringGrid(Sender).Objects[COLUMN_OBJECT, ARow]).AnaUrunId = 0)
        and (TXObject(TStringGrid(Sender).Objects[COLUMN_OBJECT, ARow]).ReferenceAnaUrunId <> 0)
        then
        begin
          FFromSatirTipi := stAlt;
          FFromUrunID := TXObject(TStringGrid(Sender).Objects[COLUMN_OBJECT, ARow]).ReferenceAnaUrunId;

          for n1 := 1 to TStringGrid(Sender).RowCount-1 do
          begin
            if Assigned(TStringGrid(Sender).Objects[COLUMN_OBJECT, n1]) then
            begin
              //seçilenin bulunduğu satır hariç seçili ana ürün altındaki tüm alt ürünlerin bulunduğu satırlara taşıma yapılabilir
              if  (TXObject(TStringGrid(Sender).Objects[COLUMN_OBJECT, n1]).AnaUrunId = 0)
              and (TXObject(TStringGrid(Sender).Objects[COLUMN_OBJECT, n1]).ReferenceAnaUrunId = FFromUrunID)
              and (n1 <> ARow)
              then
              begin
                FTasimaYapilabilirSatirlar[i] := n1;
                Inc(i);
              end
            end;
          end;
        end;
      end;
    end;
  end;
  inherited;
end;

procedure TFormX.StringGridMouseMove(Sender: TObject;
  Shift: TShiftState; X, Y: Integer);
var
  gc: TGridCoord;
  ARow: Integer;
begin
  if Sender is TStringgrid then
  begin
    if TStringGridX(Sender).FGridState = gsRowMoving then
    begin
      gc := TStringGrid(Sender).MouseCoord(X, Y);
      ARow := gc.Y;
      //mouse sınır dışına çıkarsa taşıma işlemini iptal et
      if (ARow < 1) then
      begin
        try
          TStringGridX(Sender).FGridState := gsNormal;
          TStringGrid(Sender).Repaint;
        except
        end;
      end;
    end;
  end;
  inherited;
end;

procedure TFormX.StringGridMouseUp(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  gc: TGridCoord;
  ARow, n1, i: Integer;

  function existsRowInArray(ARow: Integer): Boolean;
  var
    nx, nLen, nAdd: Integer;
  begin
    Result := False;
    nLen := Length(FTasimaYapilabilirSatirlar);
    for nx := 0 to nLen-1 do
    begin
      nAdd := 0;
      if FTasimaYapilabilirSatirlar[nx] > FFromIndex then
        if FFromIndex > ARow then
          nAdd := 0
        else if FFromIndex < ARow then
        begin
          nAdd := -1;
          if (TStringGrid(Sender).RowCount-1 = ARow)
          or (FFromSatirTipi = stAlt)
          then
            nAdd := 0;
        end;

      if FTasimaYapilabilirSatirlar[nx] + nAdd = ARow then
      begin
        Result := True;
        Exit;
      end;
    end;
  end;

begin
  if Sender is TStringgrid then
  begin
    if TStringGridX(Sender).FGridState = gsRowMoving then
    begin
      gc := TStringGrid(Sender).MouseCoord(X, Y);
      ARow := gc.Y;
      if (ARow < 0) or (FFromIndex = 0) then
        Exit;
        
      TStringGrid(Sender).Perform(WM_SETREDRAW, 0, 0);
      try
        if FFromIndex <> ARow then
        begin
          if FFromSatirTipi = stAna then
          begin
            if not existsRowInArray(ARow) then
              TStringGridX(Sender).MoveRow(ARow, FFromIndex)
            else
            begin
              //ana ürünle birlikte alt ürünleride burada taşıma yapacağız
              i := 1;
              for n1 := 1 to TStringGrid(Sender).RowCount-1 do
              begin
                if Assigned(TStringGrid(Sender).Objects[COLUMN_OBJECT, n1]) then
                  if  (TXObject(TStringGrid(Sender).Objects[COLUMN_OBJECT, n1]).AnaUrunId = 0)
                  and (TXObject(TStringGrid(Sender).Objects[COLUMN_OBJECT, n1]).ReferenceAnaUrunId = FFromUrunID)
                  then
                  begin
                    TStringGridX(Sender).MoveRow(FFromIndex + i, ARow + i);
                    Inc(i);
                  end;
              end;
            end;
          end
          else if FFromSatirTipi = stAlt then
          begin
            if not existsRowInArray(ARow) then
              TStringGridX(Sender).MoveRow(ARow, FFromIndex);
          end
          else if FFromSatirTipi = stBagimsiz then
          begin
            if not existsRowInArray(ARow) then
              TStringGridX(Sender).MoveRow(ARow, FFromIndex);
          end;

          for n1 := 1 to TStringGrid(Sender).RowCount-1 do
            if Assigned(TStringGrid(Sender).Objects[COLUMN_OBJECT, n1]) then
              TXObject(TStringGrid(Sender).Objects[COLUMN_OBJECT, n1]).SiraNo := n1;

          //sıra numaralarını sadece sınıf içinde değiştiriyoruz cell olarak grid görselinde doldurmuyoruz.
          //Sonrasında listeyi sıra numarasına göre tekrar sort ediyoruz ve gridi yeniden dolduruyoruz.
          //bu şekilde yapılmazsa object olarak doldurulduğu için ve satırlarda değiştirme yapılınca
          //form kapatılırken pointer hatası veriyor. Bu hatayı aşmak için bu işlemi yapıyoruz.
          xList.Sort(@CompareSiraNos);
          fillGrid;
        end;
      finally
        TStringGrid(Sender).Perform(WM_SETREDRAW, 1, 0);
        TStringGrid(Sender).Invalidate; // important! to force repaint after all
      end;
    end;
  end;
  inherited;
end;
PostgreSQL - Linux - Delphi, Poliüretan
WWW
Cevapla


Konu ile Alakalı Benzer Konular
Konular Yazar Yorumlar Okunma Son Yorum
  SQL Table Type parametre gecisi hakkında (Çözüldü) adelphiforumz 1 151 09-04-2026, Saat: 15:53
Son Yorum: adelphiforumz
  Stringgrid seçili sütunları aktarma cvheneburi 1 1.124 26-02-2025, Saat: 10:24
Son Yorum: delphiman
  FastReport Dinamik Sayıya Göre Etiket Bastırma [ÇÖZÜLDÜ] bünyamin68 2 752 09-01-2025, Saat: 13:47
Son Yorum: bünyamin68
  paslibvlcplayerin gec acilmasi sorunu-COZULDU sadikacar60 7 1.151 08-10-2024, Saat: 09:25
Son Yorum: mrmarman
  [Çözüldü] HTTP üzerinden RTSP ile IP kamera stream işlemek Abdullah ILGAZ 4 6.867 08-10-2024, Saat: 09:20
Son Yorum: sadikacar60



Konuyu Okuyanlar: 1 Ziyaretçi