Kent Olsen
asked on
Drag and Drop in a TStringGrid
I've got a new application with a TStringGrid that contains simple text. I'd like to be able to swap the contents of two cells with a simple drag and drop but this seems to be a control that doesn't behave as expected.
When I click on a cell, the cell highlights by a double line around the cell. If I click on another control the cell background changes color and looks like a normal highlighted cell.
I cannot drop to a cell. The OnClick() method is called and I can clearly see that I'm entering the cell, but the OnDragDrop() method is never called.
Any thoughts on how to use this control would be appreciated.
Thanks,
Kent
When I click on a cell, the cell highlights by a double line around the cell. If I click on another control the cell background changes color and looks like a normal highlighted cell.
I cannot drop to a cell. The OnClick() method is called and I can clearly see that I'm entering the cell, but the OnDragDrop() method is never called.
Any thoughts on how to use this control would be appreciated.
Thanks,
Kent
Sorry... Misunderstand the question.
Hummm... interesting problem, both source and destin are the same component...
Let's think a bit more...
Jose
Hummm... interesting problem, both source and destin are the same component...
Let's think a bit more...
Jose
ASKER
Yeah. :) This is an interesting poser that has a real use.
The simplest thing may be to just use a different type of control, but at this point I'd rather see if a reasonable solution exists.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Ahhh... Just use the MouseDown and MouseUp events.....
Sometimes the simple solutions evade us. I'll try it. :)
ASKER
Hi Jose,
That worked better than I could have possibly hoped. :) kudos.
I'm going to post the basic code and leave the question open for a few more days. This new EE protocol seems to bury the new questions as soon as they are closed.
Kent
// Set DragMode to dmManual
// Set goEditing to true
// In MainForm
bool Swapping; // Set to false in the instantiator
int SwapFromX;
int SwapFromY;
// Methods
void __fastcall TMainForm::GridMouseDown(T Object *Sender,
TMouseButton Button, TShiftState Shift, int X, int Y)
{
Grid->MouseToCell (X, Y, SwapFromX, SwapFromY);
if (SwapFromX < Grid->ColCount && SwapFromY < Grid->RowCount)
{
StatusBar->SimpleText = Format ("Swap: (%s) [Drag the mouse to the name you wish to swap]",
ARRAYOFCONST ((DrawingGrid->Cells[SwapF romX][Swap FromY])));
Swapping =true;
}
else
StatusBar->SimpleText = "";
}
//------------------------ ---------- ---------- ---------- ---------- ---------- -
void __fastcall TMainForm::GridMouseMove(T Object *Sender,
TShiftState Shift, int X, int Y)
{
int CurrentX;
int CurrentY;
Grid->MouseToCell (X, Y, CurrentX, CurrentY);
if (Swapping && CurrentX > 0 && CurrentY > 0 &&
CurrentX < Grid->ColCount && CurrentY < Grid->RowCount &&
(CurrentX != SwapFromX || CurrentY != SwapFromY))
StatusBar->SimpleText = Format ("Swap: (%s) with (%s)",
ARRAYOFCONST ((Grid->Cells[SwapFromX][S wapFromY], Grid->Cells[CurrentX][Curr entY])));
else
StatusBar->SimpleText = "";
}
//------------------------ ---------- ---------- ---------- ---------- ---------- -
void __fastcall TMainForm::GridMouseUp(TOb ject *Sender,
TMouseButton Button, TShiftState Shift, int X, int Y)
{
String S;
int CurrentX;
int CurrentY;
Grid->MouseToCell (X, Y, CurrentX, CurrentY);
if (Swapping && CurrentX > 0 && CurrentY > 0 &&
CurrentX < Grid->ColCount && CurrentY < Grid->RowCount &&
(CurrentX != SwapFromX || CurrentY != SwapFromY))
{
S = Grid->Cells[CurrentX][Curr entY];
Grid->Cells[CurrentX][Curr entY] = Grid->Cells[SwapFromX][Swa pFromY];
Grid->Cells[SwapFromX][Swa pFromY] = S;
}
Swapping = false;
}
That worked better than I could have possibly hoped. :) kudos.
I'm going to post the basic code and leave the question open for a few more days. This new EE protocol seems to bury the new questions as soon as they are closed.
Kent
// Set DragMode to dmManual
// Set goEditing to true
// In MainForm
bool Swapping; // Set to false in the instantiator
int SwapFromX;
int SwapFromY;
// Methods
void __fastcall TMainForm::GridMouseDown(T
TMouseButton Button, TShiftState Shift, int X, int Y)
{
Grid->MouseToCell (X, Y, SwapFromX, SwapFromY);
if (SwapFromX < Grid->ColCount && SwapFromY < Grid->RowCount)
{
StatusBar->SimpleText = Format ("Swap: (%s) [Drag the mouse to the name you wish to swap]",
ARRAYOFCONST ((DrawingGrid->Cells[SwapF
Swapping =true;
}
else
StatusBar->SimpleText = "";
}
//------------------------
void __fastcall TMainForm::GridMouseMove(T
TShiftState Shift, int X, int Y)
{
int CurrentX;
int CurrentY;
Grid->MouseToCell (X, Y, CurrentX, CurrentY);
if (Swapping && CurrentX > 0 && CurrentY > 0 &&
CurrentX < Grid->ColCount && CurrentY < Grid->RowCount &&
(CurrentX != SwapFromX || CurrentY != SwapFromY))
StatusBar->SimpleText = Format ("Swap: (%s) with (%s)",
ARRAYOFCONST ((Grid->Cells[SwapFromX][S
else
StatusBar->SimpleText = "";
}
//------------------------
void __fastcall TMainForm::GridMouseUp(TOb
TMouseButton Button, TShiftState Shift, int X, int Y)
{
String S;
int CurrentX;
int CurrentY;
Grid->MouseToCell (X, Y, CurrentX, CurrentY);
if (Swapping && CurrentX > 0 && CurrentY > 0 &&
CurrentX < Grid->ColCount && CurrentY < Grid->RowCount &&
(CurrentX != SwapFromX || CurrentY != SwapFromY))
{
S = Grid->Cells[CurrentX][Curr
Grid->Cells[CurrentX][Curr
Grid->Cells[SwapFromX][Swa
}
Swapping = false;
}
Hummm.. with improvements and a touch of coding elegance!
Jose
Jose
ASKER
Oops. :)
It needs another improvement. It doesn't differentiate between the left and right mouse buttons.
Do you really think this programming stuff is ever going to catch on? ;)
Yes, I think so. Conceptually, seems to be correct. Of course, turn this piece of code part of a commercial product will spend some extra effort, for exemple, in the differentiation of left/right button, as you have noticed (by accepting just mbLeft, for example) or adding columns/rows swapping (by accepting row and col zero).
When running your code I've changed DrawingGrid to Grid in the status bar text creation, as DrawingGrid didn't run in my environment (Builder 6).
When running your code I've changed DrawingGrid to Grid in the status bar text creation, as DrawingGrid didn't run in my environment (Builder 6).
ASKER
Hi Jose,
DrawingGrid was the name of the object in my application. That seemed confusing for this kind of post so I changed the name to "Grid". Guess that I missed one. :/
Other small improvements include checking the value of Swapping before calling MouseToCell(), etc.
Thanks again for a great suggestion!
Kent
Anything else?
ASKER
I've been out for the past week so I never got back to close this question.
Consider it closed and thanks again,
Kent
Let's use three TLabel (Label1, Label2 and Label3) all with DragMode set to dmAutomatic.
And one TStringGrid (StringGrid1).
Use the code below to drag the caption from each label to any cell at the grid.
//------------------------
void __fastcall TForm1::StringGrid1DragOve
TObject *Source, int X, int Y, TDragState State, bool &Accept)
{
Accept = Source->ClassNameIs("TLabe
}
//------------------------
void __fastcall TForm1::StringGrid1DragDro
TObject *Source, int X, int Y)
{
if (Sender->ClassNameIs("TStr
{
TStringGrid *DestGrid = (TStringGrid *)Sender;
int localCol=X/StringGrid1->De
int localRow=Y/StringGrid1->De
DestGrid->Cells[localCol][
}
}
Jose