Yorumları: 510
Konuları: 64
Kayıt Tarihi: 05-02-2017
Aktif Kullandığınız Delphi Sürümü:
- Delphi 10.2
- Delphi 10.1
- Delphi 7
Rep Puanı: 3.355 Uzman
17-03-2020, Saat: 09:13
(Son Düzenleme: 23-03-2020, Saat: 14:59, Düzenleyen: 3ddark.)
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..
Yorumları: 1.499
Konuları: 83
Kayıt Tarihi: 05-08-2016
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 12.314 Üstad
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...
Yorumları: 645
Konuları: 85
Kayıt Tarihi: 04-10-2017
Aktif Kullandığınız Delphi Sürümü:
- Delphi 11
- Delphi 10.4
- Delphi 10.3
- Delphi 10.2
- Delphi 10.1
- Delphi 10
- Delphi XE Serisi
Rep Puanı: 2.772 Uzman
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..
Yorumları: 510
Konuları: 64
Kayıt Tarihi: 05-02-2017
Aktif Kullandığınız Delphi Sürümü:
- Delphi 10.2
- Delphi 10.1
- Delphi 7
Rep Puanı: 3.355 Uzman
(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;
Yorumları: 510
Konuları: 64
Kayıt Tarihi: 05-02-2017
Aktif Kullandığınız Delphi Sürümü:
- Delphi 10.2
- Delphi 10.1
- Delphi 7
Rep Puanı: 3.355 Uzman
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.
Yorumları: 1.499
Konuları: 83
Kayıt Tarihi: 05-08-2016
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 12.314 Üstad
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...
Yorumları: 510
Konuları: 64
Kayıt Tarihi: 05-02-2017
Aktif Kullandığınız Delphi Sürümü:
- Delphi 10.2
- Delphi 10.1
- Delphi 7
Rep Puanı: 3.355 Uzman
@ 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.
Yorumları: 510
Konuları: 64
Kayıt Tarihi: 05-02-2017
Aktif Kullandığınız Delphi Sürümü:
- Delphi 10.2
- Delphi 10.1
- Delphi 7
Rep Puanı: 3.355 Uzman
23-03-2020, Saat: 13:08
(Son Düzenleme: 23-03-2020, Saat: 13:57, Düzenleyen: 3ddark.
Sebep: çözüldü
)
Çö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;
|